57

How do I dump an internal vim command (not shell command) into a new buffer?

For example, I want to dump a listing of all plugins into :enew from :scriptnames so that I can search it.

1

5 Answers 5

72

You can use :redir to redirect the output to a variable, register, or file. Example of redirecting to the unnamed register:

:redir @">|silent scriptnames|redir END|enew|put

Alternatively Tim Pope's scriptease.vim provides the :Scriptnames command which will load :scriptnames into the quickfix list and :copen.

If you find yourself redirecting many commands you may want to wrap up this up in a command:

command! -nargs=+ -complete=command Redir let s:reg = @@ | redir @"> | silent execute <q-args> | redir END | new | pu | 1,2d_ | let @@ = s:reg

Now you can use the :Redir command to redirect the output to a new buffer. e.g. :Redir scriptnames or :Redir ls.

Vim 8+

Vim 8 ships with the new execute() function. You can use the execute() function to instead of :redir to capture ex-command output.

 :enew|pu=execute('scriptnames') 

For more help see:

:h :redir
:h :silent
:h :scriptnames
:h :enew
:h :put
:h execute()
4
  • What does END mean? Commented Jun 22, 2016 at 17:00
  • 1
    It stops redirecting the output to the register so you can have regular output again.
    – Tumbler41
    Commented Jun 22, 2016 at 17:01
  • 1
    :redir END tells Vim to end redirecting messages. See :h :redir Commented Jun 22, 2016 at 17:01
  • To execute an external command and capture its output in a Vim variable, use system(). :let hostname = system('hostname') Commented Jul 29, 2017 at 8:37
8

For completeness, I want to present this awesome functions that I collected (stole) from romainl

" redirect the output of a Vim or external command into a scratch buffer
function! Redir(cmd)
  if a:cmd =~ '^!'
    execute "let output = system('" . substitute(a:cmd, '^!', '', '') . "')"
  else
    redir => output
    execute a:cmd
    redir END
  endif
  tabnew
  setlocal nobuflisted buftype=nofile bufhidden=wipe noswapfile
  call setline(1, split(output, "\n"))
  put! = a:cmd
  put = '----'
endfunction
command! -nargs=1 Redir silent call Redir(<f-args>)

This will take normal or system command output and put it in a new tab. Feel free to change the line tabnew to vnew or new etc.

(new and vnew are alternatives to split and vsplit as the output would otherwise be printed in your current file)

1
6

To understand easily, I splitted full command into small sub commands:

  1. Redirect to register "

  2. Execute the actual command. Go till the end of output.

  3. Stop redirect.

  4. Open new buffer and paste from register "

    :redir @"
    :map
    :redir END
    :enew|put
    
5

There's also the bufferize.vim plugin:

:Bufferize scriptnames

which is basically a packaged version of the accepted answer (using :redir) and may be more convenient for some.

0

the best solution is with the asyncrun plugin (requiring vim8+): https://github.com/skywind3000/asyncrun.vim

:AsyncRun -mode=term -pos=bottom -rows=15 -cols=40 -focus=0 pwd

will open a 15 rows terminal at bottom, run the linux command pwd and display the output there.

read its wiki for more info.

2
  • 4
    The OP is looking to capture the output of a Vim command, not a shell command.
    – Rich
    Commented Feb 5, 2020 at 17:30
  • Thanks, came up while searching for exactly this... agree this is "wrong" re answering OP's q...
    – batFINGER
    Commented Mar 22, 2021 at 7:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.