35

How can I pipe the output of a shell command into a new buffer in Vim? The following obviously wouldn't work, but you can see what I'm getting at:

:!echo % | :newtab
27

You can't pipe the output of a shell command into a command that creates a new buffer, but you can create a new buffer and read the output of a shell command into that buffer with one entry on Vim's command line. A working version of your example would be

:tabnew | r !echo <c-r>=bufname("#")<cr>

Note that the pipe symbol in this case is a separator between Vim ex commands, not the shell's pipe. See also

:help :tabnew
:help :r!
:help :bar
  • That's almost exactly what I need, just the other way around so that I can access the filename of the current buffer. Note: updated the question to hopefully clarify the desired end result. – Richie Marquez Jun 29 '10 at 6:44
  • @Richard Marquez: i updated this answer. the new tab is now opened with the "old" filename, thus you could call :!echo % – akira Jun 29 '10 at 8:24
  • But not :r!echo without altering the buffer. – Luc Hermitte Jun 29 '10 at 9:27
  • 2
    @garyjohn, akira: thanks for the help. The "<c-r>=..." part made Vim spew errors, but I was able to get it working with ":tabnew | r !echo #". – Richie Marquez Jun 29 '10 at 14:22
  • 1
    Might also be useful to note that if you want to map this to a key in your .vimrc, you'll need to replace the | character with <bar>. – Richie Marquez Jun 29 '10 at 18:15
16

Here's what I do. It's alluded to in comments in the above answers.

:new | r ! <cmd>
:new | r ! <cmd> #   (# is replaced with filename)

Example 1: Find all text files in /tmp

:new | r ! find /tmp -name '*.txt'

Example 2: You're editing file foo.txt and you want to run ls -la foo.txt and get the output in a buffer:

:new | r ! ls -la #

The # is replaced with the filename of the original buffer you're editing. This is particularly useful for ad-hoc source control commands e.g.

:new | r ! hg annotate -un #

:new creates a horizontal split, use :vnew if you want a vertical split instead and :tabnew for a new tab.

  • Are you able to answer this question here as well? it is about trying to use the current buffer with % for the next buffer but E499. – hhh Jul 20 '17 at 19:28
4
:tabnew | enew | r ! <your shell cmd>

works for me.

2

If you really require to store the result in a new buffer, but require info from the old current buffer, then you can either use system():

:let res = system('echo '.expand('%'))
:tabnew
:put=res

or store the current buffer name for later:

:let bn = expand('%')
:tabnew | :r!echo <c-r>=bn<cr>
  • see the other answer, you can do it without storing the name in a variable. but good answer anyway. – akira Jun 29 '10 at 11:12
  • Indeed. I wasn't sure '#' will give the expected result in that case -- as I never use tabs – Luc Hermitte Jun 29 '10 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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