I have a keybinding that works:

inoremap <silent> <Tab> <C-r>=
  \ pumvisible() ? "\<lt>C-N>" :
  \ CursorAfterOnlyWhitespace() ? "\<lt>Tab>" :
  \ "\<lt>C-\>\<lt>C-O>:ALEComplete\<lt>CR>"<CR>

I tried to put it in a function that takes arguments:

function! TabComplete(complete, indent)
  if pumvisible()
    " Tab through completions.
    return a:complete
  if CursorAfterOnlyWhitespace()
    " Indent.
    return a:indent
  " Find completions.
  return '\<C-\>\<C-O>:ALEComplete\<CR>'

inoremap <silent> <Tab> <C-R>=TabComplete('\<lt>C-N>', '\<lt>Tab>')<CR>
inoremap <silent> <S-Tab> <C-R>=TabComplete('\<lt>C-P>', '\<lt>S-Tab>')<CR>

But this does not work. It just inserts the literal string returned by the function. How do I get Vim to decode the control characters in the string returned by my function?

1 Answer 1


Replace the single quotes with double quotes.

return "\<C-\>\<C-O>:ALEComplete\<CR>"

Single quoted Strings are "literal strings". Every character is used as entered. They are useful to express regular expressions etc as you don't have to double the backslashes.

In double quoted strings backslash-escapes like \<C-O> are interpreted as one character.

See :help literal-string and :help String.

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.