在vim中将ex命令重定向到STDOUT



我正在尝试编写一个命令来将vim的高亮显示信息转储到STDOUT。我可以像这样成功地写入文件:

vim +'redir >outfile' +'hi' +'redir END' +'q'

之后,outfile包含了我想要的内容。但我宁愿输出到STDOUT,以管道到一个命令,该命令将高亮显示信息转换为CSS。

这种方法尝试将命令重定向到寄存器,写入当前缓冲区,然后将输出发送到tee

vim -E +'redir @a' +'silent! hi' +'redir END' +'put a' +'w !tee' +'q!' > outfile

这很接近,但是输出一个前导分页消息(多255行…)和一些ANSI转义在最后。设置nomore并不能使消息消失。我希望将第一个命令中发送到outfile的确切输出发送到STDOUT。

Vim支持输出到标准输出,我们可以将其重定向到标准输出来解决您的问题。不过要注意,这个特性仅用于调试目的,因此它有一些缺点。这里有一个关于如何做到这一点的简短草图。

首先,我们将在静默批处理模式下运行Vim,这是通过-e -s标志(:h -s-ex)启用的。我们禁用交换文件-n,因为如果我们需要在Vim卡住时杀死它,它们会很麻烦。

我们没有将Ex命令作为命令行参数传递,而是使用-S源脚本文件。创建一个包含以下内容的文件hi.vim:

verbose highlight

:verbose是使Vim输出:highlight消息到stderr所必需的。让我们看看目前为止我们有什么:

$ vim -n -e -s -S hi.vim

不要运行这个,否则你会被困在一个无头Vim的黑暗中!

添加:quit命令并将stderr重定向到stdout:

$ vim -n -e -s -S hi.vim +quit 2>&1

瞧!现在把这些乱七八糟的东西放到你想要的任何文件或实用程序中。

关于这个主题有一篇非常详尽的wiki文章,"Vim作为vimscript的系统解释器"。


优点:由于Vim与终端环境的交互方式,它不能在批处理模式输出中编写正确的unix LF行结尾。相反,它写的行结束符看起来像CRLF行结束符。

考虑添加一个过滤器来删除那些:

$ vim -n -e -s -S hi.vim +quit 2>&1 | tr -d 'r' | my-css-util

这回答了如何"在vim中将ex命令重定向到STDOUT"的一般问题,但它不一定适用于:hi问题,因为-e -s标志造成了这个约束:

没有使用'term'和$ term。

如果你在Unix兼容的环境下工作,你总是可以使用一个特殊的文件,例如:

ex +"redir>>/dev/stdout | hi | redir END" -scq!

这将把任何Vi/Ex命令打印到标准输出中,您可以进一步解析。

我在运行第一个命令时错误地遇到了这个问题。当我第二次运行它的时候,它跳出来了。我想这是因为文件已经存在了。所以你可以尝试(发送到已经存在的东西):

vim +'redir >/dev/null' +'hi' +'redir END' +'q'

最新更新