Vim r! in cursor position

vim

with vim, if I use

:r!date

vim insert the date in the next line, similar with

:r!pwd

how I can insert the output command under cursor position and no in a new line ?

Best Answer

With ":read" Vim will always insert the output on a new line. The solution is unfortunately not simple.

You may insert the output of a command at the current cursor position when you are in insert mode by pressing ControlR then typing =system('command')Enter. Unfortunately, if the command's output has a trailing newline (as most will) that will also be inserted, so your line will be broken.

That can be fixed by adding a substitute() call to strip trailing newlines, but that makes the command more trouble than it is worth to type out by hand.

The ultimate solution is to create some sort of mapping, but that gets even more complex due to how Vim handles what it calls "type ahead"; while you can do something like:

:nmap \e i<c-r>=substitute(system('date'),'[\r\n]*$','','')<cr><esc>

Where the command is "hard wired" in the mapping, you cannot do something like:

:nmap \e i<c-r>=substitute(system(input('Command: ')),'[\r\n]*$','','')<cr><esc>

Where you try to prompt the user for the command to run, because Vim will just get confused, beep, and enter insert mode.

So you have to prompt for the command to run first, store it in a variable, and then insert the processed output. At this point a helper function is probably needed to keep the mapping itself from becoming unmanageably messy, so we end up with something like this:

function InlineCommand()
    let l:cmd = input('Command: ')
    let l:output = system(l:cmd)
    let l:output = substitute(l:output, '[\r\n]*$', '', '')
    execute 'normal i' . l:output
endfunction

nmap <silent> \e :call InlineCommand()<CR>

Note that nmap creates mappings that only execute when typed in normal mode.

Incidentally, if you only wanted to insert the date or the current working directory, the initial answer I gave is feasible. Just enter insert mode and type ControlR=strftime('%c')Enter or ControlR=getcwd()Enter.

Related Question