Vim自定义替换功能

时间:2017-12-19 15:28:09

标签: vim replace vi neovim

注意:我目前正在使用Neovim v0.2.2(但我相信这不应该改变与此帖相关的任何内容)

我目前正在尝试在vim中创建一个允许轻松替换文本的功能。

我知道我可以创建一个快捷方式和宏以及所有这些,但理想情况下我只想提供2个参数,而不是考虑哪些细节会在哪里,因为这可以中断我的思维过程。

所以我决定将一个简单的包装器伪装成一个函数(我将创建一个命令包装器,一旦我弄清楚我在这里做错了什么)

function! VisualReplace(query, replacement)
" Example = '<,'>s/query\%V/replacement/g
'<,'>s/a:query\%V/a:replacement/g
endfunction

正如您所看到的,它是一个非常简单的功能,只是将args应用于它的各自位置。然而,即使在使用以下函数调用函数时,这也会失败:call VisualReplace('some_query', 'some_replacement'

或者,如果您只是使用我直接注释掉的示例,那就没有问题,所以我希望someoen可以启发我的潜在修复

如果需要,我可以看看弦乐建设&amp;逐步建立

错误消息: 找不到模式:a:查询\%V

2 个答案:

答案 0 :(得分:4)

一般理论

Vimscript的评估方式与:命令行中输入的Ex命令完全相同。 ex中没有变量,因此无法指定它们。以交互方式键入命令时,您可能使用<C-R>=插入变量内容:

:sleep <C-R>=timetowait<CR>m<CR>

...但在脚本中,必须使用:execute。必须引用Ex命令的所有文字部分(单引号或双引号),然后与变量连接:

execute 'sleep' timetowait . 'm'

您的功能

要将a:querya:replacement参数转换为:substitute,请使用:execute字符串连接printf()

function! VisualReplace(query, replacement)
    execute "'<,'>s/" . a:query . '\%V/' . a:replacement . '/g'
endfunction

其他批评

将范围传递给函数是如此常见,它有特殊的语法糖:range属性为:functiona:firstlinea:lastline隐含的论点。在:help function-range-example了解更多相关信息。虽然这里的用例似乎是专门针对可视模式的,但一般来说,保持功能范围尽可能广泛是有用的。

答案 1 :(得分:1)

@Ingo Karkat完美回答。但是,我觉得可能有一些工作流程可能有所帮助。 (假设您没有尝试编写此行为的脚本)

Visual Star

看起来您正在构建基于视觉部分的搜索。您可能需要考虑使用visual-star plugin来简化流程。以下是视觉星形映射的示例:

xnoremap * :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>/\V<c-r>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr><cr>

此映射将允许您直观地选择文本,然后执行*以使其成为搜索模式。与*在正常模式下在当前word上的工作方式类似。

搜索精炼

我的印象是您正在尝试优化搜索模式。使用q/或在使用<c-f>搜索时按/,Vim可以很好地执行此操作。见:h q/。这将打开命令行窗口,允许您使用所有普通的Vim键编辑查询/命令行。

使用gn动作

进行搜索和替换

有时做替换只是矫枉过正,或者并不适合这种情况。您可以使用gn动作来模拟搜索和替换,以对搜索模式进行操作。通过使用运算符和gn运动,您可以使用点命令.轻松地重复操作。

示例:

/foo
cgnbar<esc>

现在,您可以使用.重复foo - &gt; bar替换。使用n跳过。您也可以使用其他运算符,例如gU为大写。

请参阅:h gn:h operator以获取更多帮助。

相关Vimcasts集: