Redirect ex command to STDOUT in vim
Asked Answered
C

3

5

I'm trying to craft a command to dump vim's highlighting information to STDOUT. I can write successfully to a file like this:

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

After this, outfile contains exactly what I want. But I'd rather output to STDOUT to pipe to a command which converts that highlighting info to CSS.

This approach tries to redirect the command to a register, write to the current buffer, then send that output to tee.

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

This is pretty close, but outputs a leading paging message (255 more lines...) and some ANSI escape crap at the end. Setting nomore did not squelch the message for me. I'm looking to send the exact output sent to outfile in the first command to STDOUT.

Cryptomeria answered 24/5, 2013 at 16:10 Comment(3)
I am not sure if this could be an option for you: vim +'redir! >outfile' +'silent! hi' +'redir END' +'q'&&cat outfileCubeb
Why don't you use the built-in :TOhtml?Penelopa
@Penelopa for some reason TOhtml is not outputting the correct colors for me.Cryptomeria
P
9

Vim supports outputting to stderr, which we can redirect to stdout to solve your problem. Careful though, this feature is intended only for debugging purposes, so it has a few edges. Here's a short sketch of how you could do this.

First, we will be running Vim in silent or batch mode, which is enabled with the -e -s flags (:h -s-ex). We disable swap files -n because they will be a bother if we need to kill Vim when it gets stuck.

Instead of passing Ex commands as command line arguments we source a script file with -S. Create a file hi.vim with the following contents:

verbose highlight

:verbose is necessary to make Vim output the :highlight message to stderr. Let's see what we have so far:

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

Don't run this yet or you'll get stuck in the darkness of a headless Vim!

Add a :quit command and redirect stderr to stdout:

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

Voilà! Now pipe this mess into any file or utility at your heart's desire.

There's a very thorough wiki article on this topic, "Vim as a system interpreter for vimscript".


Finer points: Due to how Vim interacts with the terminal environment it can't write proper unix LF line endings in batch mode output. Instead it writes line endings which look like CRLF line endings.

Consider adding a filter to get rid of those:

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

This answers the general question of how to "Redirect ex command to STDOUT in vim", but it doesn't necessarily work for your :hi problem, because of this constraint caused by the -e -s flags:

'term' and $TERM are not used.

Paillette answered 25/5, 2013 at 20:24 Comment(2)
Great general answer! For the particular problem, I would rather investigate why :TOhtml doesn't work. Its maintainer is on vim_dev and very helpful.Dmz
Awesome answer. True master of the dark arts. :)Ikeda
F
2

If you're working with Unix compatible environment, you can always use a special file, e.g.:

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

This will print any Vi/Ex command into standard output which you can parse further.

Flanker answered 17/10, 2015 at 19:27 Comment(0)
N
1

I ran into this by mistake while running your first command. The second time I ran it, it went to stdout. I guess this is because the file already existed. So you can try (sending to something that already exists):

vim +'redir >/dev/null' +'hi' +'redir END' +'q'
Norry answered 28/5, 2013 at 12:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.