7

It is possible to pipe visually selected lines (i.e. selected with uppercase V) using :, after which I can enter a command in vim's command line, e.g.:

:'<,'>!python -m base64 -d

I'd like to do the same for the selected character range (i.e. selected with lowercase v). Using : still creates a linewise range (:'<'>). Trying to manually provide a character range like this:

:`<,`>!python -m base64 -d

Still does not work; it outputs this:

E492: Not an editor command: `<`>!python -m base64 -d

The question: How can I pipe visually selected characters to a system (cmd) program?

3

2 Answers 2

3

You can define a function in your .vimrc:

    function! GetVisualSelection()
    let [lnum1, col1] = getpos("'<")[1:2]
    let [lnum2, col2] = getpos("'>")[1:2]
    let lines = getline(lnum1, lnum2)
    let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)]
    let lines[0] = lines[0][col1 - 1:]
    return join(lines, "\\n")
endfunction

And then execute something like this: <C-u>exe "!echo \"" . GetVisualSelection() . "\" | python -m base64 -d"

To give credits I took function from this SO answer, only change is last line to include double backslash to make it work in shell.

1
  • This is an excellent answer, and the correct one if we have to use !. Otherwise, the answer @Sundeep has suggested (see my own answer) is much simpler and achieve the same result. Yours however will also work with block mode. Note that I have marked the question as a duplicate. Thanks! Commented Oct 12, 2016 at 12:52
2

If someone looks for an answer, here is the one from Replace selection with output of external command

  • c to put the visually selected text in the default ("") register
  • Ctrl+r to execute a Vim command
  • = to use the execute register
  • system('whatever command', @") to pass the default register (@") to the system command
  • Enter to execute the command
  • Esc to return to the normal mode

This can be remapped to a shortcut

vnoremap <silent> <leader>btoa c<c-r>=system('base64 --decode --wrap=0', @")<cr><esc>

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