vim:基于一个命令运行多个命令:global command

时间:2017-07-29 14:25:42

标签: vim vi ex

道歉,如果已经发布,因为我找不到答案,即使在vim维基上也是如此。

有没有办法可以在单个:g搜索中以vim命令行模式运行多个命令?

例如,

:%g/foo/ s/bar/\=@a/g | exe "norm /cat\<enter>\"ayiw"

对于foo匹配的每一行,(我打算这样做)应该将bar替换为注册a的内容,然后然后找到cat的下一次迭代(即使前面有很多行),并将周围的单词放入寄存器a

相反,此特定语法使用初始a寄存器的当前内容完成subsitution命令,然后在一行上执行正常模式命令(在替换完成后)。

此示例不是我的特定用例,但显示了此功能有用的一个实例。我意识到我可以把它全部放到一个exe中,即%g/foo/exe "norm :s/bar/\\=@a/g\<enter>/cat\<enter>\"ayiw",但我想先做第一种方式,因为我觉得它更灵活。


我更喜欢使用vanilla vim来做这件事,但是如果有一个插件,这是一个不错的选择。有没有人知道是否有语法来做这样的事情?

2 个答案:

答案 0 :(得分:1)

好吧“有点”脏,但这对你有用吗?

:let list = split(execute('g/cat/p'), '\n') | g/foo/ s/bar/\=matchstr(remove(list, 0), '\s\d\+\s\zs.*')/g

它首先读取cat的所有出现,将它们保存在列表中。 然后用第一只猫替换第一个bar ......依此类推。

脏部分是matchstr命令。 g//p也返回结果的数字,因此列表如下所示:

 1 cat
 2 cat
 3 cat
 ...

这就是为什么我们必须从前面删除一点。我很想知道是否有人知道一个干净的解决方案(我也对干净的vimscript解决方案感兴趣,不一定是oneliner)。

答案 1 :(得分:0)

您可以执行此操作(至少对于应用于一个:g的多个:s命令而言)。示例:

" SHORT STORY TITLES to single word of CapitalizedWords within <h3>s
.,$g/^\L\+$/s/[^A-Z0-9 ]\+//ge|s/\u\+/\L&/ge|s/\<\l\+\>/\u&/ge|s/ \+//ge|s/.*/<h3>&<\/h3>/