假设我有以下文本文件
name: John Doe
description: My name is John Doe and I'm really good at vim!
name: John Doe
description: My name is John Doe and I'm really good at vim!
name: John Doe
description: My name is John Doe and I'm really good at vim!
name: John Doe
description: My name is John Doe and I'm really good at vim!
是否有一种方法可以录制执行以下操作的宏:
从第一个John
开始:
cw
,但允许运行宏的用户给予此处输入js<is>w
在is之后偷偷输入单词.
用给定的输入替换John
1.重复播放
理想情况下,我希望在第一行输入以下键击:@qJane
且具有:
name: Jane Doe
description: My name is Jane Doe and I'm really good at vim!
@qJim
name: Jim Doe
description: My name is Jim Doe and I'm really good at vim!
2条答案
按热度按时间ctehm74n1#
接受用户输入的最简单方法是使用
input()
函数,该函数允许您提示输入名称并在表达式中使用它。不幸的是,您不能真正从宏中使用它,因为宏也会记录您对提示符的回答(并且重放您构建的宏也会有类似的问题)。
您可以通过函数使用它,并将该函数绑定到键Map:
然后您可以键入
\cn
,系统将提示您输入新名称。键入新名称并按Enter后,系统将用新名称替换出现的前两个John
。该函数返回Map的扩展,在map命令中使用
<expr>
以使其使用该函数的返回值。(让该函数发出带有:execute
的:normal!
命令也是一种可能的方法。)您提到了按
@qJim
或@qJane
,此时没有提示符,并且新名称“感觉”像是命令的一部分。通过在Map背后的函数的循环中使用getchar()
,可以更接近于这样的操作。您仍然需要决定如何终止名称,你会在最后按回车键吗?你会用计时来决定命令什么时候结束吗如果使用getchar()
,您可能还需要处理退格和取消命令。使用input()
当然更容易,并且根据您的特定用例可能已经足够了。5n0oy7gb2#
虽然
q
经常与术语 macro 一起使用,但其目的只是记录和重复字符序列。重复是这里的关键-如果您的目的不是重复完全相同的序列,那么q
可能不是理想的解决方案。使用map应该可以很容易地实现这一点(注意,
:h macro
会将您指向:map
)。可以使用:execute
构建一个命令,用input()
返回的任何内容替换当前行和下一行中第一个出现的 John。后者负责提示用户。下面是一个Map到
,n
的小例子:如果您不知道要替换的名称,您也可以询问:
或者使用一个正则表达式来捕获“name”后面的第一个单词,忽略“:“或“is”: