2013-01-10 102 views
3

我在我的.vimrc中为我使用的版本控制系统写了一些宏(Perforce)(请不要为vim提供perforce插件,我试过了,我不喜欢它)。他们都能正常工作,除了恢复宏,由于确认提示而断开(我需要这样做,所以我不会无意中将我的更改变胖)。目前,它看起来像这样:vim:使用确认键映射命令

map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 | !p4 revert <C-R>=expand("%:p")<CR><CR><CR>:edit<CR> | endif 

这会导致bash的时候Vim试图加载该文件在抱怨:

bin/bash: -c: line 0: syntax error near unexpected token `(' 

望着缓冲的bash看到,它看起来像错误是,VIM将其发送第一根管子后面的所有东西,而不仅仅是用于bash的部分。我尝试了一些替代方案,但似乎无法使其发挥作用。当我删除管道和endif(使用速记if)时,我已经准确地显示了确认对话框,但是当用户给出响应后,vim会发出抱怨。

回答

3

使用管道将多个vim命令串起来并不是特别明确,并且有很多偏心。关键的是,(见:help :bar)它不能在类似shell命令:!的命令之后使用,该命令将|字符看作其参数。

您可能会发现使用system()函数更容易。

E.G.如果你有这样的文件名空格或引号字符(或已经巧妙地命名它; rm -rf ~(不要在家里尝试!))

:echo system("p4 revert " . shellescape(expand("%:p"))) 

shellescape()包装是非常有用的。

在创造更多可读/可维护的代码的兴趣,你可能会想你的代码放入一个函数:

function Revert() 
    if confirm('Revert to original?', "&Yes\n&No", 1)==1 
     return system("p4 revert " . shellescape(expand("%:p"))) 
    endif 
endfunction 

,你会在你的宏中使用:call:echo命令来访问。

+0

解决方案中存在一个小错误,该命令需要“p4还原”,而不是“p4”,但整体格式起作用。谢谢 –

4

我想你想沿着这些路线的东西:

: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',这显然不是你想要的。

建立起来一块在时间,从内到外:

  1. 有你有时想运行shell命令。
  2. 该shell命令需要位于:if之内才能执行“有时”位,因此在其后面有:endif
  3. 在文字!后面的所有内容都传递给shell,包括|字符,这些字符通常表示另一个Vim命令的启动。这是合理的,因为|是在shell命令中使用的非常好的字符。所以我们需要一些包含shell命令的方法。 :exe可以做到这一点;它执行提供的字符串作为命令 - 它的参数是一个字符串,它有一个定义的结束。所以一般形式是:if condition | exe "!shell command" | endif
  4. 你的shell命令中有一个表达式。使用:exe可以简化这一操作,因为您可以简单地将命令的字符串常量部分与表达式的结果连接起来。因此,该命令变为:exe "!p4 revert" . expand("%:p") - 在文件上自行尝试,然后在继续之前检查它是否符合要求。
  5. 把它放在条件内可以让你:if confirm('Revert to original?', "&Yes\n&No", 1)==1 | exe "!p4 revert" . expand("%:p") | edit | endif - 在定义映射之前再次尝试一下。
  6. 一旦你有这个工作,定义映射。一个文字|确实结束了映射并表示下一个Vim命令的开始。在你原来的映射定义中,只有在条件结束时(在加载文件后用:map <F8>进行检查),并且!p4部分在定义映射的Vim文件上立即运行!您需要将您的命令中的每个|更改为<Bar>,与您的命令中每个按Enter需要编写为<CR>的方式类似。这给你上面的映射。首先在命令行中输入它,然后再次执行:map <F8>以检查它是什么您认为它是。只有然后尝试按F8
  7. 如果可行,请将映射放入您的.vimrc
+0

谢谢,不幸的是我只能接受一个答案,但我也赞成你的答案。 –