接受用户输入的 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!
name: John Doe
description: My name is John Doe and I'm really good at vim!

有没有办法录制执行以下操作的宏:

从第一个John开始:

  1. cw但允许运行宏的用户在此处提供输入

  2. js<is>w偷偷把这个词放在后面

  3. .将 John 替换为给定的输入
  4. 重复

理想情况下,我想在第一行输入以下击键:

@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!

获取用户输入的最简单方法是使用input()函数,该函数允许您提示输入名称并在表达式中使用它。

不幸的是,您不能真正从宏中使用它,因为宏也会记录您对提示的回答(重播您构建的答案会遇到类似的问题。

不过,您可以从函数中使用它,并将该函数绑定到键映射:

function! ChangeName()
let newname = input('Name? ')
return '0/<John>'."<cr>cw".newname."<esc>n."
endfunction
nnoremap <expr> <leader>cn ChangeName()

然后,您可以键入cn,这将提示您输入新名称。键入新名称并按 Enter 后,它将用新名称替换出现的前两次John

该函数返回映射的扩展,使用 map 命令中的<expr>使其使用函数的返回值。(让函数发出带有:execute:normal!命令也是一种可能的方法。

您提到按@qJim@qJane,那里没有提示,新名称"感觉"像命令的一部分。通过在映射背后的函数循环中使用getchar(),可以更接近类似的东西。您仍然需要决定如何终止名称,您会在最后使用 ENTER 吗?你会使用时间来决定命令何时结束(需要快速键入吗?如果您使用getchar(),您可能还需要处理退格键和取消命令。使用input()当然更容易,并且可能足够,具体取决于您的特定用例。

尽管q经常与术语一起使用,但其 目的是简单地记录和重复一系列 字符。在这里重复关键 - 如果你的意图是 不重复相同的确切顺序,那么q可能是 不是理想的解决方案。

您应该能够通过地图轻松实现此目的 (请注意,:h macro会指向:map(。您可以使用:execute构建一个替换第一个的命令约翰在当前行和之后的行中的出现次数 无论input()有什么回报。后者负责 用于提示用户。

下面是一个实现映射到,n的小示例:

:nnoremap ,n :exe ',+s/John/' . input('Name: ')<CR>

如果您不知道要替换的名称,可以要求 那也是:

:nnoremap ,n :exe ',+s/' . input('Old name: ') . '/' . input('New name: ')<CR>

或者使用正则表达式来捕获"name"后的第一个单词 忽略":"或"是":

:nnoremap ,n :exe ',+s/vname(: | is )+zsw+/' . input('New name: ')<CR>

相关内容

  • 没有找到相关文章

最新更新