我已经在我的 .vimrc 中为我正在使用的版本控制系统 (Perforce) 编写了一些宏(请不要为 vim 推荐 perforce 插件,我试过了,但我不喜欢它)。除了恢复宏之外,它们都可以正常工作,由于确认提示而中断(这是我需要的,所以我不会不小心将我的更改变胖)。它目前看起来像这样:
map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 | !p4 revert <C-R>=expand("%:p")<CR><CR><CR>:edit<CR> | endif
当 vim 尝试加载文件时,这会导致 bash 提示:
bin/bash: -c: line 0: syntax error near unexpected token `('
查看bash看到的缓冲区,错误似乎是vim在第一个管道之后将所有内容发送给它,而不仅仅是用于bash的部分。我尝试了一些替代方法,但似乎无法使其正常工作。当我删除管道和 endif(使用速记 if)时,我已经让它正确显示确认对话框,但是在用户给出响应后 vim 会提示。
最佳答案
我想你想要这样的东西:
:map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 <Bar> exe "!p4 revert" . expand("%:p") <Bar> edit <Bar> endif<CR><CR>
请记住
:map
是一个愚蠢的按键序列:你在映射什么F8
to 必须是一系列可以在键入时起作用的击键。 A <CR>
在:if
的中间声明并不意味着“然后按 Enter
”如果条件为真,此时执行命令时';意思是‘按 Enter
在这里输入 :if
命令”,这显然不是您想要的。从内到外,一次次地构建它:
:if
内做“有时”的事情,所以有一个 :endif
跟随它。 !
之后接下来的所有内容都传递给shell,包括|
通常表示另一个 Vim 命令开始的字符。这是合理的,因为 |
是一个非常适合在 shell 命令中使用的字符。所以我们需要某种方式来包含 shell 命令。 :exe
可以这样做;它将提供的字符串作为命令执行——它的参数是一个字符串,有一个定义的结尾。所以一般形式是:if condition | exe "!shell command" | endif
. :exe
使这变得容易,因为您可以简单地将命令的字符串常量部分与表达式的结果连接起来。所以命令变成 :exe "!p4 revert" . expand("%:p")
- 在文件上单独尝试一下,并在进一步操作之前检查它是否满足您的要求。 :if confirm('Revert to original?', "&Yes\n&No", 1)==1 | exe "!p4 revert" . expand("%:p") | edit | endif
- 在定义映射之前再次尝试。 |
结束映射并表示下一个 Vim 命令的开始。在您的原始文件中,映射定义仅到达条件的末尾(加载文件后用 :map <F8>
检查)和 !p4
部分立即在定义映射的 Vim 文件上运行!您需要更改每个|
在您的命令中输入 <Bar>
,类似于每次按 Enter
在您的命令中需要写为 <CR>
.这为您提供了上面的映射。先在命令行输入试试,然后做 :map <F8>
再次检查它是你认为的那样。然后才尝试按 F8
. 关于vim:带有确认键的映射命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14268232/