How can I redirect or pipe the output of an ex command into my current buffer or a file?
For example, I want to read the contents of all the registers into the current buffer, which in ex mode is shown using :registers
.
:redir >name_of_registers_file
:registers
:redir END
:r name_of_registers_file
:help redir
The last command is very useful, since there are lots of options for redirection: to variables, to registers, how to append, further cornucopia.
I still find it weird and annoying that it uses END that way, but since everything else that can follow redir
has to start with a non-word-character, at least it's not ambiguous.
PS AFAIK (which is pretty far in this case) there's no way to read it directly into the buffer: you have to store it in a register or a variable first. Check the help for the various options of how to do that.
PPS If you do want to do this using a variable —maybe to encapsulate it in a function and avoid clobbering registers or global variables— you'll have to convert the multiline string that gets written to the variable into a list. EG
:call append( '.', split(variable_you_redirected_to, "\n") )
Otherwise (if you just do append('.',var)
) you end up with ^@'s (nulls) instead of newlines, since that's what vimscript uses to represent newlines in String variables.
edit: as @Bill Odom mentions, using :put =variable_you_redirected_to
is a lot easier than the complicated append()
expression. Thanks, Bill!
I've written a snippet to make this stuff more convenient. It declares a function Redir(command, target)
and a command R
.
The command parses the last series of non-space characters as a redirection target and passes that to the function, which does the boilerplate to redirect the command output to the redirection target.
The command is everything after R
and before the last space.
EG
" Store the vim buffer list in buffer_list.txt
:R ls >buffer_list.txt
" Store error messages emitted by a function being debugged
" in the 'unnamed register'
:R call FunctionBeingDebugged() @">
There are a few limitations with this: for example you won't be able to write to a filename that contains a space. The upside to this is that you don't have to quote your command. I've got it posted on gist.github.com, and I'll try to keep it updated if I end up improving it. Or you can fork it yourself</noeuphemism>!
Anyway the snippet is available here. It can be dropped into a .vimrc file or into a file in ~/.vim/plugins.