I have a function that I want returning pre-indented xml:

function! InsertStep()
    let stepTemplate = "<step index=\"\">\n
    \  <description></description>\n
    \  <update>\n
    \    <label></label>\n
    \    <value></value>\n
    \    <type>Expression</type>\n
    \  </update>\n
    return stepTemplate

And here is my mapping for it:

imap <silent> <C-S><C-S> <C-R>=InsertStep()<CR>

But when I'm in insert mode and press my ctrl+s, ctrl+s hotkey, the result is not formatted:

<step index="">

Looking at this, it seems to drop my cursor down with smart indentation or something for every newline in the returned text or something. I have smart indent off btw. I would expect, if I'm just inserting the function's result at the cursor location, that there should not be any auto-indent shenanigans.


  • 1
    Welcome to Vi and Vim! You might find it easier to write your code using join([long list], "\n") instead--then you can also use single-quotes and avoid some escaping.
    – D. Ben Knoble
    May 22, 2021 at 14:06

1 Answer 1


Here, instead of a straight <C-R>, you will want to use one of <C-R><C-O>, if you'd prefer to strip all auto-indent, or <C-R><C-P>, if you would like to have Vim adjust the indentation of the inserted block.

If you'd like to strip all indentation, same as if the 'autoindent' option is disabled:

inoremap <silent> <C-S><C-S> <C-R><C-O>=InsertStep()<CR>

Note that this doesn't strip the indentation of the first line that gets inserted, so you might want to compensate for that, for example by using something like <C-U> or 0<C-D> at the start of the mapping to remove indentation (or even the contents) of the first line before inserting the result of the expression.

If, on the other hand, you'd like Vim to adjust the indentation of the inserted block, you can use the following:

inoremap <silent> <C-S><C-S> <C-R><C-P>=InsertStep()<CR>

This might be more appropriate for a block that can be inserted at any depth of indentation (as is typically the case with HTML or XML), so perhaps this is the best option here. But it's possible that the result will not match exactly what you had in mind, since I believe Vim will not really reindent the whole block (using 'shiftwidth' and other indentation options such as 'indentexpr'), but will just repeat the indentation present in the first line for the rest of the block (as far as I can tell.) Still, this might be enough, if your function is able to produce a multi-line string with the appropriate formatting and just needs adjustment of the initial indentation.

  • 1
    beautiful, <C-R><C-O> worked perfectly! thanks for the detailed response
    – jbu
    May 22, 2021 at 17:06

Your Answer

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

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