关于在 vim 命令模式下使用 shell 管道的困惑

Confusion about using shell pipes from vim command mode

我有一个函数(写在下面;来源:TeX SX 上的TeX SX) that uses pipes in the shell which I'd like to use in vim command mode. It works as intended from the shell but returns an E34: No previous command error if entered in vim command mode. Full credit goes to jirislav in this post

: | pdflatex -halt-on-error src.tex | grep '^!.*' -A200 --color=always

如果有人可以提供帮助,我非常希望从 vim 命令行获得此 shell 功能。

我在 vim 命令模式下尝试了以下操作:

:! : | pdflatex -halt-on-error src.tex | grep '^!.*' -A200 --color=always

returns E34 错误。没有管道隐藏所有编译;但是,它也不会输出错误。删除 2 个管道中的 1 个对我来说也是 returns E34 错误。

我尝试了进一步的故障排除但没有成功,下面是一些结果。的帮助:!说

a pipe '|' in {cmd} is passed to the shell, you cannot use it to append a vim command. See :bar

and :bar 说(我认为这被称为转义)

'|' can be used to separate commands, so you can give multiple commands in one line. If you want to use '|' in an argument, precede it with '\'.

我尝试按照 :bar 的建议进行操作,即

:! : \| pdflatex -halt-on-error src.tex \| grep '^!.*' -A200 --color=always

结果是它隐藏了一切,包括我想看到的编译错误。所以我得出的结论是,我不知道如何在 vim 命令模式下正确使用 shell 管道。

如果您不是 LaTeX 用户,则该函数的全部功能如下。 pdflatex 将 vim 中发生的事情编译成 pdf 文件。制定:!来自 vim 的命令模式的 pdflatex % 输出大量处理文本并中断工作流程;函数中的 grep 会清除编译错误(如果存在)。然后,该函数旨在隐藏 pdflatex 的所有输出,除非发生编译错误,在这种情况下,它仅输出错误并以红色输出。

如果有人愿意解释 E34 错误以及为什么它不起作用,我们也将不胜感激。

编辑 1:感谢 filbranden,现在 已解决。下面附有几张最小示例的图片,以防以后有人遇到这个问题。

vim file before input, output

编辑 2:如果你想把它放在你的 .vimrc 文件中,你需要在 grep 之前退出管道,否则 vimrc file 默认认为管道是分隔符。

E34: 没有之前的命令

所以你的问题的答案隐藏在 :help E34 下,重定向到 :! 命令。

(Vim 专业提示:每当您从 Vim 收到错误时,请在错误代码上询问 :help 以获得更多相关信息。)

:! 部分包括这段话:

Any ! in {cmd} is replaced with the previous external command. But not when there is a backslash before the '!', then that backslash is removed.

做了在你的命令中有一个!,作为grep正则表达式^!.*的一部分,所以那是触发"history" 行为,试图替换为先前执行的命令。但由于此时没有执行任何命令,该命令因错误而失败。

您可以通过使用反斜杠转义 ! 来解决它,Vim 将在将命令传递给 shell 之前删除反斜杠:

:! pdflatex -halt-on-error src.tex | grep '^\!.*' -A200 --color=always

但请注意,有更好的方法来解决这个问题!让我介绍其中的一些。

使用系统列表()

在 Vim 中 运行 外部命令的一个好方法是使用 systemlist() 函数,运行 是 shell 上的命令,捕获其输出,将其拆分为行和 returns 包含结果输出行的列表。

所以你可以从:

开始
let latex_output = systemlist('pdflatex -halt-on-error src.tex')

然后使用Vim脚本命令检查以!开头的行以报告给用户。

请注意,与 :! 不同,systemlist() 的输出永远不会显示给用户(这意味着您不会切换回看到终端,可能是空白终端,并且执行后你没有“Hit enter prompt.)这太棒了!

但这意味着您需要在出现错误时向用户显示该信息。一个很好的方法是使用 quickfix window!

您可以使用setqflist()函数来设置quickfix的内容window。

(为了获得最佳效果,您应该适当地设置 'errorformat',稍后会详细介绍。)

使用vim-调度

如果您不喜欢 运行ning 外部命令(通过 :!systemlist())的部分 block Vim直到命令执行完成,再考虑安装vim-dispatch插件

它可以在后台或在单独的终端中为您执行命令,因此您不会被阻止编辑。它还集成了 :make 命令和 quickfix window.

vim-latex

中的编译器配置

最后,vim-latex插件(也称为latex-suite)有配置帮助你运行pdflatex和报告错误。

它包含一个Vim :compiler configuration that will run pdflatex for you as a :make program. It also will set 'errorformat'来识别! LaTeX Error字符串并识别错误的行号,因此您可以直接从quickfix列表跳转到它们。

请注意 vim-latex 还有许多其他功能可以帮助您在 Vim 中编写 LaTeX 文档(除了通过编译器支持管理输出生成之外。)您可能需要检查这些其他功能也是如此。

(由于该插件有很多功能,我建议您阅读整个文档以开始使用它。)

另请注意,此插件与 vim-dispatch 兼容(因为 vim-latex 提供编译器接口,而 vim-dispatch 使用它),因此您可以两个都喜欢就一起用吧!