vim:map命令,带确认键

vim:map命令,带确认键,vim,Vim,我已经在我的.vimrc中为我正在使用的版本控制系统(Perforce)编写了一些宏(请不要推荐用于vim的Perforce插件,我试过了,我不喜欢它)。它们都可以正常工作,但revert宏除外,该宏由于确认提示而中断(我需要确认提示,这样我就不会意外地丢失更改)。目前看起来是这样的: map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 | !p4 revert <C-R>=expa

我已经在我的.vimrc中为我正在使用的版本控制系统(Perforce)编写了一些宏(请不要推荐用于vim的Perforce插件,我试过了,我不喜欢它)。它们都可以正常工作,但revert宏除外,该宏由于确认提示而中断(我需要确认提示,这样我就不会意外地丢失更改)。目前看起来是这样的:

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在第一个管道之后发送所有内容,而不仅仅是用于bash的部分。我尝试了一些替代方案,但似乎无法奏效。当我移除管道和endif(使用缩写if)时,我已经让它正确地显示确认对话框,但是在用户给出响应后,vim会抱怨。

使用管道将多个vim命令串在一起的定义不是特别明确,而且有许多偏心。关键的是,(请参阅)它不能在shell命令
:这样的命令之后使用
|
字符视为其参数

您可能会发现使用该函数更容易

例如

如果文件名中有空格或引号之类的字符(或者巧妙地将其命名为
;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
命令来访问它。

我想您需要以下内容:

:map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 <Bar> exe "!p4 revert" . expand("%:p") <Bar> edit <Bar> endif<CR><CR>
:映射:如果确认('Revert to original?',“&Yes\n&No”,1)==1 exe”!p4 Revert”。展开(“%:p”)编辑结束
请记住,
:map
是一个愚蠢的击键序列:您要将
F8
映射到的必须是一个击键序列,如果键入该序列,该序列将起作用。<代码>中的<<代码> <代码>:如果语句在执行该命令时,并不意味着'和按下<代码>输入< /代码>,如果条件为真;这意味着“按下<代码>输入< /代码>这里,当在<代码>中键入:如果命令,这显然不是你想要的。< /P> 从内到外,一次构建一块:

  • 有时您需要运行一个shell命令
  • 该shell命令需要位于
    :if
    中才能执行“有时”位,因此后面有一个
    :endif
  • 在文字
    之后以下所有内容都传递给shell,包括通常表示另一个Vim命令开始的
    |
    字符。这是合理的,因为在shell命令中使用
    |
    是一个非常好的字符。因此,我们需要某种方法来包含shell命令
    :exe
    可以执行此操作;它以命令的形式执行提供的字符串,并且它的参数(作为字符串)有一个已定义的结尾。因此,一般形式是
    :if条件| exe“!shell命令”| endif
  • 您的shell命令中有一个表达式。使用
    :exe
    可以简化此操作,因为您可以简单地将命令的字符串常量部分与表达式的结果连接起来。因此,命令变为
    :exe“!p4 revert”。展开(“%:p”)
    -在文件上单独尝试,并在继续之前检查它是否执行了您想要的操作
  • 将其放入条件中会给出
    :如果确认(‘还原为原始?’,“&Yes\n&No”,1)==1 | exe”!p4 Revert”。展开(“%:p”)|编辑| endif
    -在定义映射之前再次尝试
  • 一旦你有工作,定义映射。文本
    |
    结束映射并表示下一个Vim命令的开始。在您的原始映射定义中,映射定义仅到达条件的末尾(加载文件后用
    :map
    检查它)和
    !p4
    零件正在定义映射的Vim文件上立即运行!您需要将命令中的每个
    |
    更改为
    ,类似于在命令中每次按
    Enter
    都需要写入
    。这为您提供了上面的映射。首先在命令行中键入它,然后再次执行
    :map
    ,检查它是否符合您的想法。然后才尝试按F8
  • 如果这样做有效,请将映射放在.vimrc中

  • 解决方案中有一个小错误,该命令需要“p4 revert”,而不是“p4”,但总的来说格式是有效的。谢谢谢谢,不幸的是我只能接受一个答案,但我也投了你的一票。
    function Revert()
        if confirm('Revert to original?', "&Yes\n&No", 1)==1
            return system("p4 revert " . shellescape(expand("%:p")))
        endif
    endfunction
    
    :map <F8> :if confirm('Revert to original?', "&Yes\n&No", 1)==1 <Bar> exe "!p4 revert" . expand("%:p") <Bar> edit <Bar> endif<CR><CR>