Sunday, March 30, 2008

Inserting command output from a function

How would I use a vim function to insert the output of these commands at the current cursor position?

Well, that would look like a crude hack, yet here it goes:

:function InsertCmd( cmd )
: exe ':silent !'.a:cmd.' > /tmp/ 2>/dev/null'
: let l = readfile( '/tmp/', '', 1 )
: exe "normal a".l[0]
: redraw!

:imap <silent> <F5> <Esc>:call InsertCmd( 'hostname' )<CR><Insert>
:map <silent> <F5> :call InsertCmd( 'hostname' )<CR>

The function InsertCmd(cmd) runs in shell given command and redirects its stdout to a file. Then using readfile() function, first line of file is read into list l. Finally using :normal command and a (:help a) command we put the first line of output into buffer.

The two mappings for F5 key - for insert and for command mode show how to invoke the function to insert output of "hostname" into current cursor position. ":imap" probably needs extra <Right> on the end since due to switch between insert/normal modes cursor goes one position back.

Edit1. Better way to do it, from SO.


Anonymous said...


:r! [command]

Ihar Filipau said...

Problem with ":r!" is that it inserts lines.

e.g. if you want to insert simply host name in the string in code - output of "hostname" or "uname -n" - then it is too much trouble to use ":r!" because it would insert host name on new line.

Though yes, it is kind of silly. But writing the function was entertaining. ^_^

Anonymous said...

Took me a while to find out that it can be done easier:

nnoremap ^silent^ ^F6^ :execute "normal a".system("hostname")[:-2]^CR^

P.S.: replace "^" with the appropriate chars that this blog won't accept but interpret as HTML tags.