tags:

views:

196

answers:

2

Hi

How can I read the output of an ex command into my current buffer?

For example, I want to read the contents of all the registers into the current buffer, which in ex mode is shown using ":registers"

Thanks

+5  A: 
: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, appending, 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!


PPPS

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.

intuited
A: 

@intuited is right; the redir command is what you want. A one-liner like this will insert the output of :registers into the current buffer:

redir => m | silent registers | redir END | put=m

That's not something you'll want to type very often, however, and it's not exactly amenable to a key map. I found myself doing this fairly often, so I wrote a function and a handful of commands to make it easier. As a bonus, I can now send command output to a new window or new tab as easily as inserting it into the current buffer. Here's the code (with a few command examples at the very end):

" redir_messages.vim
"
" Inspired by the TabMessage function/command combo found
" at <http://www.jukie.net/~bart/conf/vimrc&gt;.
"

function! RedirMessages(msgcmd, destcmd)
"
" Captures the output generated by executing a:msgcmd, then places this
" output in the current buffer.
"
" If the a:destcmd parameter is not empty, a:destcmd is executed
" before the output is put into the buffer. This can be used to open a
" new window, new tab, etc., before :put'ing the output into the
" destination buffer.
"
" Examples:
"
"   " Insert the output of :registers into the current buffer.
"   call RedirMessages('registers', '')
"
"   " Output :registers into the buffer of a new window.
"   call RedirMessages('registers', 'new')
"
"   " Output :registers into a new vertically-split window.
"   call RedirMessages('registers', 'vnew')
"
"   " Output :registers to a new tab.
"   call RedirMessages('registers', 'tabnew')
"
" Commands for common cases are defined immediately after the
" function; see below.
"
    " Redirect messages to a variable.
    "
    redir => message

    " Execute the specified Ex command, capturing any messages
    " that it generates into the message variable.
    "
    silent execute a:msgcmd

    " Turn off redirection.
    "
    redir END

    " If a destination-generating command was specified, execute it to
    " open the destination. (This is usually something like :tabnew or
    " :new, but can be any Ex command.)
    "
    " If no command is provided, output will be placed in the current
    " buffer.
    "
    if strlen(a:destcmd) " destcmd is not an empty string
        silent execute a:destcmd
    endif

    " Place the messages in the destination buffer.
    "
    silent put=message

endfunction

" Create commands to make RedirMessages() easier to use interactively.
" Here are some examples of their use:
"
"   :BufMessage registers
"   :WinMessage ls
"   :TabMessage echo "Key mappings for Control+A:" | map <C-A>
"
command! -nargs=+ -complete=command BufMessage call RedirMessages(<q-args>, ''       )
command! -nargs=+ -complete=command WinMessage call RedirMessages(<q-args>, 'new'    )
command! -nargs=+ -complete=command TabMessage call RedirMessages(<q-args>, 'tabnew' )

" end redir_messages.vim
Bill Odom
Nice, I didn't realize you could just `:put =var`.
intuited