【问题标题】:Pipe a vim command after a shell command在 shell 命令之后通过管道传递 vim 命令
【发布时间】:2017-05-18 23:10:35
【问题描述】:

我正在尝试在 vim 中创建一个键映射,它 (a) 保存当前文件 (b) 执行 git 操作,使用 shell (c) 退出当前 vim 编辑器。

我尝试了以下方法,但仍然无法弄清楚。

方法一 - 在 Vim 命令行中

:w | !git commit -am "auto" | q

方法2 - 在.vimrc中

map :W :w \| !git commit -am "auto"

map :L :Wq

问题

问题是管道| 只能用于附加shell 命令。我该怎么做'a Vim command' + 'a shell command' + 'a Vim command'?如何在 shell 命令之后通过管道传递 vim 命令?

【问题讨论】:

  • 这绝对不是@Barmar标记的问题的重复!我已经描述得很清楚了。 问题在于管道 |只能用于附加shell命令。 Barmar提到的问题仅适用于纯shell命令管道。相比之下,我的问题要求结合 一个 shell 命令和一个 vim 命令
  • 另一个问题是关于运行两个vim 命令。其中一个命令恰好是执行 shell 命令的! 命令,但这两个命令可以是任何命令。
  • pdflatexgit 不是vim commands,它们是shell commands。您必须使用 ! 在 vi​​m 中执行它们。在我的问题中,q 将被转换为!qq (in bash) 并产生错误。
  • 顺便说一句,短语vim commands 不是代码,不应在反引号中引用。考虑斜体强调。顺便说一句,你们都介意链接到提议的欺骗,以便其他人有上下文就此事做出明智的决定吗?
  • :!according to the docs 之后不能使用管道。

标签: bash shell vim


【解决方案1】:

您需要分别执行这三个命令。这就是<CR> 的用途:

nnoremap <key> :w<CR>:!git commit -am "auto"<CR>:qa<CR>

【讨论】:

  • 想通了!
【解决方案2】:

你试过vim-fugitive吗?

您可以使用该插件git commit -am,然后添加您的 git 命令。

所以你会这样写:

Gcommit -am "auto"

我对其进行了简单的测试。我已经把它放到了我的 .vimrc 中:

function! CommitAndQuit()
    execute "Gcommit -am 'auto'"
    execute "q"
endfunction

然后输入:call CommitAndQuit(),它会做你想做的事。

【讨论】:

    【解决方案3】:

    当我来到这里时,这感觉很相关!

    因此,如果您想在命令中绑定它,您将无法使用&lt;cr&gt;,并且管道也将不起作用。

    在这种情况下,正确的做法是使用一个函数,然后从该命令调用该函数。

    在这个例子中,我有一个 shell 脚本来 grep 一些日志文件中的错误并将结果输出到 .errors,然后在 quickfix 中打开它。重绘是因为静默会用外部命令弄乱你的屏幕!

    function! ReadErrors()
      silent !read-errors
      redraw!
      cfile .errors
    endfunction
    
    command! ReadErrors call ReadErrors()
    

    【讨论】:

      【解决方案4】:

      我在这里看到了 3 种情况:

      添加 vim 命令

      如果您想添加一个新的 vim 命令,以便输入 :W 将写入缓冲区,执行 git commit 并退出 vim,您需要遵循 JonnyRaa 的回答。即定义一个函数,然后定义一个执行该函数的命令:

      function! WriteCommitAndQuit()
          w
          silent !git commit -am "auto"
          q
      endfunction
      command! W WriteCommitAndQuit()
      

      注意事项:

      1. 这些行可以放在 ~/.vimrc 中,或者在点击: 后直接执行以进入命令行模式。
      2. 我使用 silent 来避免出现“按 ENTER 或键入命令继续”提示。
      3. 您可能希望使用writequit 而不是wq,以获得更好看的代码。 (相反,如果您赶时间,silent 可以缩短为 sil...)

      添加键盘映射

      如果您只想按一个键来运行这些命令,则需要添加一个映射,将 shell 命令放在中间的技巧是使用&lt;CR&gt; 模拟按 ENTER :

      map <F10> :w<CR>:silent !git commit -am "auto"<CR>:q<CR>
      

      注意事项:

      1. 再一次,这可以进入 ~/.vimrc 或通过点击 : 并直接输入来执行。
      2. 除了silent,您可以在shell 命令后添加一个额外的&lt;CR&gt;

      直接执行

      有时您想重复运行一系列命令,但它们不值得费心坚持到 vimrc 中,因为它们是临时的,将来不会有用。在这种情况下,我只是执行该行,然后依靠向上箭头再次从历史记录中取出该行并执行它。 在这种情况下,诀窍是在命令中间添加一个转义的 LF 字符,使用 Ctrl-V、Ctrl-J:

      :w | silent !git commit -am "auto" ^@ q
      

      注意事项:

      1. 命令中的^@ 是我按Ctrl-V、Ctrl-J 时显示的内容。如果您按 Shift-6、Shift-2,它将不起作用。但是,如果我按 Ctrl-Shift-2,它似乎确实有效。
      2. 您也可以将第一个竖线字符替换为 LF,但您不必这样做。
      3. 如果您好奇的话,Ctrl-J 是 LF,因为 LF 是 ASCII 10,而 J 是 ABC 的第 10 个字母。同样,Ctrl-I 是 Tab,Ctrl-M 是 CR,Ctrl-] 是 Escape,因为 Escape 是 ASCII 27,如果你查看 ASCII table,你会发现 ] 是第 27 个字母ABC。

      【讨论】:

        【解决方案5】:

        You can't:

        一个'|'在 {cmd} 被传递给 shell,你不能用它来附加一个 Vim 命令。见 |:bar|。

        【讨论】:

        • 是的,这个事实已经在问题中说明了,就像在这句话中,问题是管道|只能用于附加 shell 命令。
        【解决方案6】:

        我使用此命令将当前文件路径复制到系统剪贴板。

        map <silent> <leader>vv :echo expand('%:p') \| !syscopy.sh <cr>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-18
          • 2020-03-28
          • 1970-01-01
          • 2016-05-22
          相关资源
          最近更新 更多