1

Lets say I have a text file open in Vim, that looks like so

this is an inline insertion

and I want to add the word "test" between "inline" and "insertion".

I could just write it in, but this is a metaphoric example, so I'm going to :read !printf "test " with the cursor at column 18. Here's what I get:

this is an inline insertion
test

Here's what I want to get:

this is an inline test insertion

Is there any way to create a vim function or is there an existing command I can use to get this behavior? I know I could do the read, then do D k, then place the cursor, then P, but I was hoping to find a way to do this in one step, placing the cursor ahead of time.

EDIT

Thanks to @melpomene's answer, I have this function in my ~/.vimrc file now:

fu! InlineRead(command)
  let colnum = col('.')
  let line = getline('.')
  call setline('.', strpart(line, 0, colnum) . system(a:command) . strpart(line, colnum))
endfu

2 Answers 2

3

You can do it manually by combining a few other functions:

:call setline('.', strpart(getline('.'), 0, col('.')) . system('printf "test "') . strpart(getline('.'), col('.')))

Of course you can simplify this a bit by assigning the results of e.g. col('.') and getline('.') to variables, removing redundant computation:

let c = col('.')
let line = getline('.')
call setline('.', strpart(line, 0, c) . system('printf "test "') . strpart(line, c))
Sign up to request clarification or add additional context in comments.

Comments

0

Without any setup (as in @melpomene's answer), you can directly insert external command output via :help c_CTRL-R, the expression register (:help quote=), and :help system() in insert mode:

<C-R>=system('printf "test "')<CR>

An alternative implementation is the following <C-R>` mapping for insert and command-line mode:

custom mapping

" i_CTRL-R_`        Insert the output of an external command.
" c_CTRL-R_`
function! s:QueryExternalCommand( newlineReplacement )
    call inputsave()
    let l:command = input('$ ', '', 'shellcmd')
    call inputrestore()
    return (empty(l:command) ?
    \   '' :
    \   substitute(substitute(l:command, '\n\+$', '', ''), '\n', a:newlineReplacement, 'g')
    \)
endfunction
inoremap <C-r>` <C-g>u<C-r>=<SID>QueryExternalCommand('\r')<CR>
cnoremap <C-r>` <C-r>=<SID>QueryExternalCommand('\\n')<CR>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.