每一行视觉选择的 Vim 宏
Posted
技术标签:
【中文标题】每一行视觉选择的 Vim 宏【英文标题】:Vim Macro on Every Line of Visual Selection 【发布时间】:2011-03-21 06:10:30 【问题描述】:我想在选择的每一行上运行一个宏,而不是在我的脑海中计算行数。例如,我可能会编写一个宏来转换:
Last, First
进入
First Last
我希望它在所有这些行上运行:
Stewart, John
Pumpkin, Freddy
Mai, Stefan
...
Vim 大师有什么想法吗?
编辑:这只是一个示例,显然这可以简单地进行正则表达式,但还有其他实例不太容易,我更喜欢使用宏。
【问题讨论】:
老实说,我可能会用正则表达式来完成这个特殊的任务。但这个问题对于更复杂的情况仍然有效。 为什么是 vim?在我看来 sed 更合适。 @kogut : 为什么要退出编辑器以使用单行正则表达式编辑文本? 好的,你明白了;) 【参考方案1】:假设您有一个宏q
,它在一行上运行(并保持)。然后你可以在你选择的每一行上运行它:
:'<,'>normal @q
(如果您已经选择了一组行,则在命令行中点击:
会生成:'<,'>
)
例如,以下宏将除第一个单词之外的每个单词都大写:
:let @q="^dwgU$P"
所以在下面运行它(+
行被选中)
0000: a long long time ago
0001: in a galaxy far away
+0002: naboo was under an attack
+0003: and i thought me and qui-gon jinn
+0004: could talk the federation in
0005: to maybe cutting them a little slack.
使用上面的normal @q
命令,产生:
0000: a long long time ago
0001: in a galaxy far away
0002: naboo WAS UNDER AN ATTACK
0003: and I THOUGHT ME AND QUI-GON JINN
0004: could TALK THE FEDERATION IN
0005: to maybe cutting them a little slack.
【讨论】:
@Roger Pate:好吧,如果你想打高尔夫球的话:) @rampion:你的命令有错字吗?对我来说,它只能这样工作::'<,'>normal! @q
@oliver:检查你的映射——你可能已经重新映射了@q
。来自:help normal
- “如果给出 [!],则不会使用映射。”
@rampion:该死的......你是对的!我使用 yankring,显然这有一个问题:... 你不能用 ":normal @a" 执行宏。这仍然是不可能的,但您可以使用 ":normal!@a" 执行它(来自 yankring 的帮助文档)
我个人喜欢像这样在可视模式下映射@
:vnoremap @ :normal @
。这样你仍然可以像你期望的那样做@a
(尽管你必须在之后点击回车:()【参考方案2】:
选择行然后按:
进入命令模式。 Vim 会自动填写'<,'>
,它将范围限制在选定的行。对于您的示例,您可以使用 :s
命令进行交换:
:'<,'>s/\(\w\+\), \(\w\+\)/\2, \1/
这将交换视觉选择中每一行上用逗号分隔的两个单词。
您也可以像使用任何其他书签或行位置一样使用'<
和'>
,例如作为移动命令的一部分,因此在正常模式下d'<
将从当前光标位置删除到视觉选择中第一行的开头。即使块不再在视觉上突出显示,标记仍然有效。
如果您想在每一行重播录制的宏,您需要使用:normal
命令执行宏。不幸的是,:normal
命令不能在一系列行上运行,但您可以使用:global
命令修复它。这会在与正则表达式匹配的每一行上运行 :ex
命令,因此您可以这样做:
:'<,'>g/^/ norm @a
解释:
:'<,'> for every line in the visual block
g/^/ on every line that matches the regex /^/ - i.e. every line
norm run in normal mode
@a the macro recorded in a
【讨论】:
这比公认的答案更好,因为它支持添加新行的宏。 @Dave, Kirby 也许将^
与.
交换会更好,以使宏仅在包含一些文本的行上运行,不是吗?【参考方案3】:
您可以将下面的功能添加到您的~/.vimrc
或简单地将其复制到您的浏览器并运行:@+
fun! RunMacroOverSelection(macroname)
execute "'<,'>normal @". a:macroname
endfun
com -nargs=1 Rover :call RunMacroOverSelection(<f-args>)
nnoremap <leader>r :Rover<space>
优点是您可以在视觉选择上应用任何宏。 您需要将宏字母作为参数,例如:
:Rover a
【讨论】:
以上是关于每一行视觉选择的 Vim 宏的主要内容,如果未能解决你的问题,请参考以下文章