[英]vim: map command with confirmation to key
我在我的.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
映射到必须是一系列击键,如果键入的话。 在:if
语句中间的<CR>
并不意味着'并且如果条件为真,则在此时执行命令时按Enter
'; 这意味着'在输入:if
命令'的过程中按Enter
,这显然不是你想要的。
从内到外,随时将它构建成一块:
:if
要执行'有时'位,所以有一个:endif
跟随它。 !
以下所有内容都传递给shell,包括|
通常表示另一个Vim命令开始的字符。 这是合理的,因为|
是一个在shell命令中使用的完美字符。 所以我们需要一些包含shell命令的方法。 :exe
可以做到这一点; 它将提供的字符串作为命令执行 - 其参数(作为字符串)具有已定义的结尾。 所以一般形式是:if condition | exe "!shell command" | endif
:if condition | exe "!shell command" | endif
:if condition | exe "!shell command" | endif
。 :exe
使这很容易,因为您可以简单地将命令的字符串常量部分与表达式的结果连接起来。 所以命令变成:exe "!p4 revert" . expand("%:p")
:exe "!p4 revert" . expand("%:p")
- 在文件上自行尝试,并在继续之前检查它是否符合要求。 :if confirm('Revert to original?', "&Yes\\n&No", 1)==1 | exe "!p4 revert" . expand("%:p") | edit | endif
:if confirm('Revert to original?', "&Yes\\n&No", 1)==1 | exe "!p4 revert" . expand("%:p") | edit | endif
:if confirm('Revert to original?', "&Yes\\n&No", 1)==1 | exe "!p4 revert" . expand("%:p") | edit | endif
- 在定义映射之前再次尝试。 |
确实结束映射并表示下一个Vim命令的开始。 在您的原始映射定义中,仅在条件结束时(在加载文件后使用:map <F8>
检查)并且在定义映射的Vim文件上立即运行!p4
部分! 你需要改变每个|
在您的<Bar>
命令中,类似于在命令中按Enter
的方式需要写为<CR>
。 这为您提供了上面的映射。 首先在命令行输入它,然后执行:map <F8>
再次:map <F8>
以检查它是否符合您的想法。 然后尝试按F8
。 使用管道将多个vim命令串在一起并不是特别明确,并且存在许多偏心。 关键的是,(参见:help :bar
)它不能在像shell命令之类的命令之后使用:!
看到一个|
字符作为其参数。
您可能会发现使用system()
函数更容易。
例如
:echo system("p4 revert " . shellescape(expand("%:p")))
shellescape()
包装器非常有用,以防你在文件名中有空格或引号等字符(或者巧妙地命名它; rm -rf ~
(不要在家里试试!))。
为了创建更易读/可维护的代码,您可能希望将代码移动到一个函数中:
function Revert()
if confirm('Revert to original?', "&Yes\n&No", 1)==1
return system("p4 revert " . shellescape(expand("%:p")))
endif
endfunction
您可以在宏中使用:call
或:echo
命令访问它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.