使用替换命令执行()错误neovim

execute() error neovim with substitute command

我似乎无法弄清楚如何将变量设置为等于文件中的匹配项数。

我试过了

let a=execute('%s/<++>//ne')

但它不起作用(抛出此错误:

Error detected while processing function myfunctions#Tab:
line    2:
E523: Not allowed here

)。我想要一个包含正则表达式匹配次数的变量,但我似乎找不到将 execute() 函数与替换命令一起使用的方法。 (execute('%s/test//ne') 也会抛出错误)。

编辑:我正在尝试在一个称为 <expr> 映射的函数中 运行 this。完整的函数体是这样的(正确插入控制字符):

function! myfunctions#Tab()
    let a=execute('%s/<++>//ne')
    if a > 0
        return "/<++>^M:noh^Mc4l"
    else
        return "^I"
    endif
endfunction

目标是在模式 <++> 不存在时插入制表符,如果存在,则找到并替换它。我是这样映射的:

inoremap <expr> <tab> myfunctions#Tab()

您遇到此错误的原因是在 <expr> 映射中调用的函数受到限制,无法修改当前缓冲区。

来自 :help :map-expression:

Be very careful about side effects! The expression is evaluated while obtaining characters, you may very well make the command dysfunctional.

For this reason the following is blocked:

  • Changing the buffer text textlock.
  • Editing another buffer.
  • The :normal command.
  • Moving the cursor is allowed, but it is restored afterwards.

触发这种情况的是您的 :s 命令。即使您正在使用不修改缓冲区的 /n 标志,:s 命令通常会引入修改,因此在 textlock.

下完全被阻止

如果你想做的是跳到选项卡上的下一个 <++>,那么最好的选择是使用 search() 函数,它会将你的光标移动到下一个匹配项和 return 行号(非零)(如果找到匹配项)。

由于 <expr> 贴图不保留光标移动,您应该改用法线贴图。

虽然这很快变得棘手...事实证明这是最难正确的映射之一...

但要点是:您需要使用 CTRL-\ CTRL-O 暂时退出插入模式并调用您的函数。在那里,你可以做你的 search()。如果搜索匹配,您将需要调用 :stopinsert 来中断从插入模式的临时退出(实质上是永久退出)。然后你可以 运行 c4l 命令,但是你需要使用 feedkeys(),因为它最后会让你进入普通模式。

如果没有匹配项并且您想要插入制表符,则可以使用 feedkeys() 插入制表符。

综合起来:

function! myfunctions#Tab()
  if search('<++>')
    stopinsert
    call feedkeys('c4l', 'n')
  else
    call feedkeys("\t", 'n')
  endif
endfunction

inoremap <silent> <Tab> <C-\><C-o>:call myfunctions#Tab()<CR>