Vim自定义替换功能

问题描述 投票:1回答:2

注意:我目前正在使用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可以启发我的潜在修复

如果需要,我可以查看字符串构建并逐步构建它

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

vim replace vi neovim
2个回答
4
投票

General theory

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

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

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

execute 'sleep' timetowait . 'm'

Your function

为了获得a:querya:replacement参数到:substitute,使用:execute和字符串连接或printf()

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

Additional critique

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


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上以正常模式工作的方式。

Search refining

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

Search and Replace with gn motion

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

例:

/foo
cgnbar<esc>

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

有关更多帮助,请参阅:h gn:h operator

Related Vimcasts episodes:

© www.soinside.com 2019 - 2024. All rights reserved.