简体   繁体   English

vim:根据一个:global命令运行多个命令

[英]vim: Run multiple commands based off of one :global command

Apologies if this has been posted already, for I cannot find an answer, even on the vim wiki. 抱歉,如果已经发布,因为即使在vim Wiki上也找不到答案。

Is there a way I can run multiple commands in vim command-line mode off of a single :g search? 有没有一种方法可以通过单个:g搜索以vim命令行模式运行多个命令?

For example, 例如,

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

Which (for what I intend it to do) should, on every line matching foo , replace bar with the contents of register a , and then find the next iteration of cat (even if it is many lines ahead), and put the surrounding word into register a . 在与foo匹配的每一行上,哪一行(针对我打算执行的操作)应将bar替换为寄存器a的内容, 然后找到cat的下一个迭代(即使前面有很多行),并在其周围加上单词登记a

Instead, this specific syntax completes the subsitution command using the current contents of the initial a register, and then executes the normal mode command on a single line (after the substitution has been completed). 取而代之的是,此特定语法使用首字母为a寄存器的当前内容来完成替换命令,然后在一行上执行普通模式命令(替换完成后)。

This example is not my specific use-case but shows one instance where this functionality is useful. 这个示例不是我的特定用例,而是显示了一个实例,其中该功能很有用。 I realize I could put it all into a single exe , ie, %g/foo/exe "norm :s/bar/\\\\=@a/g\\<enter>/cat\\<enter>\\"ayiw" , but I would like to do it the first way, as I feel it is more flexible. 我意识到我可以将所有内容放到一个exe ,即%g/foo/exe "norm :s/bar/\\\\=@a/g\\<enter>/cat\\<enter>\\"ayiw" ,但是我想第一种方法,因为我觉得它更灵活。


I would prefer to do this using vanilla vim, but if a plugin exists for this, that is an okay alternative. 我更喜欢使用Vanilla Vim来执行此操作,但是如果存在用于此功能的插件,那是一个不错的选择。 Does anybody know if there is syntax to do such a thing? 有人知道是否有语法可以做这种事情吗?

Okay a "little bit" dirty, but does this work for you? 好吧,“有点”肮脏,但这对您有用吗?

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

It first reads all occurences of cat save them in a list. 它首先读取cat所有事件,并将它们保存在列表中。 Then replace the first bar with the first cat... and so on. 然后将第一根bar替换为第一只猫...等等。

The dirty part ist the matchstr command. 脏部分是matchstr命令。 the g//p also returns a number for the result so the list looks like this: g//p还会为结果返回一个数字,因此列表如下所示:

 1 cat
 2 cat
 3 cat
 ...

that's why we have to remove a bit from the front. 这就是为什么我们必须从前面移开一点。 I would love to hear if someone knows a clean solution for that (I am also interested in a clean vimscript solution, does not have to be a oneliner). 我很想听听是否有人为此知道一个干净的解决方案(我也对干净的vimscript解决方案感兴趣,不必成为一个单一的人)。

You can do this (at least for multiple :s commands applied to a single :g). 您可以执行此操作(至少对于应用于一个:g的多个:s命令而言)。 Example: 例:

" 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>/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM