在shell命令后面输入vim命令

7
我正在尝试在vim中进行按键映射,实现以下功能:(a) 保存当前文件 (b) 使用shell执行git操作 (c) 退出vim编辑器。我已经尝试了以下方法,但仍然无法解决问题。 方法1 - 在Vim命令行中输入: :w | !git commit -am "auto" | q 方法2 - 在 .vimrc 文件中定义快捷键: map :W :w \| !git commit -am "auto" map :L :Wq 问题 问题是管道符 | 只能用于连接shell命令。如何结合使用 '一个Vim命令' + '一个shell命令' + '一个Vim命令'呢?如何在shell命令后面加一个vim命令?

这绝对不是 @Barmar 标记问题的重复!我已经非常清楚地描述了它。问题在于管道符 | 只能用于附加 shell 命令。Barmar 提到的问题仅适用于纯 Shell 命令传递。相反,我的问题要求结合一个 Shell 命令和一个 Vim 命令! - AnnieFromTaiwan
另一个问题是关于运行两个 vim 命令。其中一个命令恰好是执行 shell 命令的 ! 命令,但这两个命令可以是任何命令。 - Barmar
pdflatexgit不是vim命令,它们是shell命令。你必须在vim中使用!来执行它们。在我的问题中,q会被翻译为!q,这是q(在bash中)并会产生错误。 - AnnieFromTaiwan
1
顺便提一下,“vim命令”这个短语不是代码,不应该用反引号引用。考虑使用斜体强调。另外,你们介意链接到建议的重复问题吗?这样其他人就可以有上下文来做出明智的决定了。 - Charles Duffy
1
根据文档,您不能在:!之后使用管道。 - Kevin
@CharlesDuffy 我提出的dup在Linked侧边栏中:https://dev59.com/YGAg5IYBdhLWcg3wwtVp?noredirect=1&lq=1 - Barmar
7个回答

4

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

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

搞定了! - JonnyRaa

1
这似乎与我最终到达的地方有关!
因此,如果您想在命令中绑定它,您将无法使用<cr>,管道也不起作用。
在这种情况下,正确的做法是使用一个函数,并从该命令中调用该函数。
在这个例子中,我有一个shell脚本来grep一些日志文件以查找错误并将结果输出到.errors中,然后在quickfix中打开。重画是因为沉默会用外部命令弄乱您的屏幕!
function! ReadErrors()
  silent !read-errors
  redraw!
  cfile .errors
endfunction

command! ReadErrors call ReadErrors()

1

你试过使用vim-fugitive吗?

你可以使用那个插件来进行git commit -am,然后添加你的git命令。

所以你可以写像这样的内容:

Gcommit -am "auto"

我简单地测试了它。我把这个东西放到了我的.vimrc文件里:

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

然后输入:call CommitAndQuit(),它将执行您想要的操作。

1
这里有三种情况:

添加vim命令

如果你想要添加一个新的vim命令,让输入:W可以写入缓存区、进行git提交并退出vim,你需要按照JonnyRaa的回答进行操作。也就是说,先定义一个函数,然后定义一个执行该函数的命令:

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

注意:

  1. 这些代码可以放在 ~/.vimrc 中,或者在按下 : 进入命令行模式后直接执行。
  2. 我使用了 silent 来避免出现 "Press ENTER or type command to continue" 的提示。
  3. 你可能想使用 writequit 而不是 wq,以获得更好的代码外观。(相反地,如果你很忙,silent 可以缩写为 sil...)

添加键盘映射

如果你想只需按下一个键就能运行这些命令,你需要添加一个映射,并且在其中插入一个 shell 命令的技巧是使用 <CR> 模拟按下回车键:

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

注意:

  1. 再次强调,这些命令可以放在 ~/.vimrc 中,或者直接通过按下 : 并直接输入来执行。
  2. 与其使用 silent,你也可以在 shell 命令后面添加一个额外的 <CR>

直接执行

有时候你想要重复执行一系列命令,但又觉得没有必要将它们保存到 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的第十个字母。同样,Ctrl-I是Tab,Ctrl-M是CR,Ctrl-]是Escape,因为Escape是ASCII 27,如果您查看ASCII表,您会意识到]是ABC的第27个字母。

0
我使用这个命令将当前文件路径复制到系统剪贴板。
map <silent> <leader>vv :echo expand('%:p') \| !syscopy.sh <cr>

0

对我来说,简单的原因是:

  • 能够工作
:echo expand('ls') | echomsg 'test'
  • 无法工作
:!ls | echomsg 'test'

-1

你不能

{cmd} 中的 '|' 被传递到 shell,你不能用它来追加 Vim 命令。请参见 |:bar|。


1
是的,这个事实已经在问题中说明了,就像这句话所说的那样,“问题在于管道符号 | 只能用于追加 shell 命令。” - AnnieFromTaiwan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接