Vim: Pipe selected text to shell cmd and receive output on vim info/command line

VimShellCommand LinePipe

Vim Problem Overview


I want to pipe the selected text to a shell command and receive the one-line output from this shell command on the vim info/command line?

What I'm really trying to do: Pipe the selected text to a pastebin-type shell command and I want to receive the output of the shell cmd (which is the http link to the pastebin). Is this possible?

Vim Solutions


Solution 1 - Vim

For multi line version you can do this after selecting the text:

:'<,'>:w !command<CR>

You can map it to simple visual mode shortcut like this:

xnoremap <leader>c <esc>:'<,'>:w !command<CR>

Hit leader key + c in visual mode to send the selected text to a stdin of the command. stdout of the command will be printed below vim's statusbar.

Real world example with CoffeeScript:

https://github.com/epeli/vimconfig/commit/4047839c4e1c294ec7e15682f68563a0dbf0ee6d

Solution 2 - Vim

Simply highlight the lines using visual line select shift-v, the hit :! and type the command you wish to send the commands to. The resulting output will then replace your selected text.

When you type your command it will appear at the bottom as:

:'<,'>!somecmd

the '<,'> is indicating that the range you have visually selected will be passed to the command specified after the !

Solution 3 - Vim

I would do it like this:

Place this function in your vimrc:

function Test() range
  echo system('echo '.shellescape(join(getline(a:firstline, a:lastline), "\n")).'| pbcopy')
endfunction

This will allow you to call this function by doing:

:'<,'>call Test()

Then you can also map that like this (just under the function declaration in your vimrc):

com -range=% -nargs=0 Test :<line1>,<line2>call Test()

So you can call the function doing this:

:'<,'>Test

Note: :<','> are range selectors, in order to produce them just select the pertinent lines in visual mode and then go to command mode (pressing the colon key)

Solution 4 - Vim

Maybe you should use something like

:echo system('echo '.shellescape(@").' | YourCommand')

Starting from some vim-7.4 version it is better to use

:echo system('YourCommand', getreg('"', 1, 1))

. This is basically the only way to keep NUL bytes untouched should they be present in the file. Passing @" in one or the other way will transform NUL bytes into NL (newline).

Solution 5 - Vim

@matias 's solution is not work well for me, because it seems shellescape will append \ to each line.

So I use sed to accomplish this, and it works just fine!

"dump selected lines
function! DumpLines() range
  echo system('sed -n '.a:firstline.','.a:lastline.'p '.expand('%'))
endfunction

com! -range=% -nargs=0 Dump :<line1>,<line2>call DumpLines()

Solution 6 - Vim

Another answer:

function Pastebin() range
    let savedreg=@"
    silent execute a:firstline.",".a:lastline."yank"
    python import vim, subprocess
    python p=subprocess.Popen(["pastebin"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    python p.stdin.write(vim.eval('@"'))
    let @"=savedreg
    python p.stdin.close()
    python retstatus=p.poll()
    python print p.stdout.read()
endfunction

Requires python support. Use it just like matias' function.

Solution 7 - Vim

An imperative way to do it is to:

  1. yank your selection
  2. drop into command mode with :
  3. ! + paste the register in the command-line like <Ctrl> r "

So: y : ! <Ctrl> r "

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionikwyl6View Question on Stackoverflow
Solution 1 - VimEpeliView Answer on Stackoverflow
Solution 2 - VimNeg_EVView Answer on Stackoverflow
Solution 3 - VimmatiasView Answer on Stackoverflow
Solution 4 - VimZyXView Answer on Stackoverflow
Solution 5 - VimHarry LeeView Answer on Stackoverflow
Solution 6 - VimZyXView Answer on Stackoverflow
Solution 7 - VimpapiroView Answer on Stackoverflow