gpt4 book ai didi

Vim 脚本 - 为所有选定的行调用一次函数

转载 作者:行者123 更新时间:2023-12-03 21:48:26 25 4
gpt4 key购买 nike

所以我有一个这样的文本文件:

Item a: <total>
Subitem: 10 min
Subitem 2: 20 min

我想更换 <total>总共 10 和 20。现在我正在使用以下功能进行操作:
let g:S = 0  "result in global variable S
function! Sum(number)
let g:S = g:S + a:number
return a:number
endfunction

function! SumSelection()
let g:S=0
'<,'>s/\d\+/\=Sum(submatch(0))/g
echo g:S
endfunction

vnoremap <s-e> call SumSelection()<cr>
Sum获取传入数字的总和, SumSelection对选定行中的所有数字调用 sum,并且(据说)Shift+e 在可视模式(或您选择的任何称呼)中调用 SumSelection。

问题是,当我选择了一些行时按下 Shift+e,而不是 :call SumSelection()真懂 :'<,'>call SumSelection()这意味着每个选定的行都会调用该函数一次。不好,对吧?所以据我所知,没有办法解决这个问题。我该怎么做才能使该功能:
  • 只被调用一次
  • 也许以更有效的方式汇总这些
  • 最佳答案

    好吧,要让函数在某个范围内只执行一次,请附加 range关键词。例如。

    fun Foo() range
    ...
    endfun

    然后您的函数可以使用特殊参数 a:firSTLine 来处理范围本身
    和一个:最后一行。 (有关详细信息,请参阅 :help a:firstline。)

    但是,我认为在这种情况下,您的要求非常简单,可以通过
    使用 :global 的单线.

    我们确实可以使用更好的指定输入和输出。但假设一个文件包含
    Item a: <total>
    Subitem: 10 min
    Subitem 2: 20 min
    Item b: <total>
    Subitem: 10 min
    Subitem 2: 23 min
    Item c: <total>
    Subitem: 10 min
    Subitem 2: 23 min
    Subitem 3: 43 min

    和定义为的函数
    fun! Sum(n)
    let g:s += a:n
    return a:n
    endfun

    然后这将对子项求和(所有一行)
    :g/^Item/ let g:s = 0 | mark a | +,-/\nItem\|\%$/ s/\v(\d+)\ze\s+min$/\=Sum(submatch(0))/g | 'a s/<total>/\=(g:s . ' min')/
    并产生这个输出
    Item a: 30 min
    Subitem: 10 min
    Subitem 2: 20 min
    Item b: 33 min
    Subitem: 10 min
    Subitem 2: 23 min
    Item c: 76 min
    Subitem: 10 min
    Subitem 2: 23 min
    Subitem 3: 43 min

    顺便说一下,上面的命令作用于整个缓冲区。如果您先突出显示一个范围,然后点击 :键,vim 会自动在你的命令前面加上 '<,'>这意味着以下命令将从突出显示范围的开始到结束进行操作。

    例如。突出显示第 1 到 5 行,然后运行命令 ( :'<,'> g/... ) 会产生此输出
    Item a: 30 min
    Subitem: 10 min
    Subitem 2: 20 min
    Item b: 33 min
    Subitem: 10 min
    Subitem 2: 23 min
    Item c: <total>
    Subitem: 10 min
    Subitem 2: 23 min
    Subitem 3: 43 min

    最后一点。如果其中一个组没有子项,例如
    Item a: <total>
    Subitem: 10 min
    Subitem 2: 20 min
    Item b: <total>
    Item c: <total>
    Subitem: 10 min
    Subitem 2: 23 min
    Subitem 3: 43 min

    那么该命令将在到达第二项时中止并显示“无效范围”错误。你可以让 Vim 忽略这个
    并通过在整个命令前加上 :silent! 来继续执行.

    编辑

    只是对我的工作流程以及为什么要使用长单线的快速解释。
  • 我喜欢 :g和 ex 命令很多。
  • 我使用命令行历史记录和命令行窗口以交互方式构建命令以进行编辑。
  • 完成后,我将像这样的一次性命令粘贴到缓冲区中:我有一个映射来将当前行作为 ex 命令执行。这样,当我需要时,命令总是很容易获得。对于更经常的使用,您可能需要一个命令、函数或 ftplugin。
  • 关于Vim 脚本 - 为所有选定的行调用一次函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8597153/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com