在vim中将重定向ex命令到标准输出

5

我想尝试编写一个命令将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 +'redir! >outfile' +'silent! hi' +'redir END' +'q'&&cat outfile - Kent
为什么不使用内置的 :TOhtml - romainl
@romainl,由于某种原因,TOhtml对我来说没有输出正确的颜色。 - Kenan Banks
3个回答

9
Vim支持输出到stderr,我们可以将其重定向到stdout以解决您的问题。不过要小心,该功能仅用于调试目的,因此有一些局限性。下面简述如何完成此操作。
首先,我们将在silentbatch mode下运行Vim,使用-e -s标志启用(:h -s-ex)。我们禁用交换文件-n,因为如果需要杀死Vim时它们会成为一个麻烦。
我们使用-S而不是将Ex命令作为命令行参数传递,来源代码脚本文件。创建一个名为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

现在,将这个混乱的内容传输到任何您想要的文件或工具中。

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


要点:由于 Vim 与终端环境的交互方式,它无法在批处理模式输出中写入正确的 Unix LF 行尾。相反,它会写入看起来像 CRLF 行尾的行尾。

考虑添加过滤器以消除这些行尾:

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

这回答了关于如何“将ex命令重定向到vim的标准输出”这个一般问题,但它不一定适用于你的:hi问题,因为由-e -s标志引起的这个限制:

'term'和$TERM未被使用。


非常好的通用答案!对于特定的问题,我更愿意调查为什么“:TOhtml”无法工作。它的维护者在vim_dev上非常乐于助人。 - Ingo Karkat
太棒了,黑暗艺术的真正大师。 :) - Darshan Sawardekar

2

如果您使用的是Unix兼容环境,您可以始终使用一个特殊的文件,例如:

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

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


1

在运行您的第一个命令时,我不小心遇到了这个问题。第二次运行时,它会输出到标准输出。我猜这是因为文件已经存在了。所以您可以尝试将其发送到已经存在的文件:

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

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