I have the following mapping:

inoremap <expr><CR> pumvisible() && complete_info().selected != -1? "\<C-y>" : "\<CR>"
inoremap <expr><Space> pumvisible() && complete_info().selected != -1? "\<C-y>" : "\<Space>"

The idea here is that if I have a completion menu open & and item selected, then pressing Enter or Space will select that item from the completion menu. Notice that <C-y> is the built-in combination to confirm a selection. This works fine.

Now, I want to expand the functionality of this so that whenever I press Space, it will select an item from the list and type a literal whitespace. I tried the following:

inoremap <expr><Space> pumvisible() && complete_info().selected != -1? "\<C-y>\<Space>" : "\<Space>"

This does not work (it behaves as if only space was pressed), & I suspect it's because the keys are sent simultaneously. I tried using a regular space character instead of the symbol and it behaved the same way. What can I do?

EDIT: Just to make my question clearer, here is what happens when I select an autocompletion option using the Enter key:

enter image description here

No problems here, all works as intended. What I want to do now is that if I had pressed Space instead of Enter, then it would do the exact same thing as it did before, but also add a whitespace at the end. With the current settings I am using, this is what happens instead:

enter image description here

  • "select and type literal" is the default behavior of vim. What do you dislike about the default way?
    – Mass
    Feb 22, 2021 at 21:08
  • It's not that I have anything against the default behaviour, it's just that I don't know how to implement what I want. Obviously, what I did does not work, so I am looking for alternatives.
    – daedsidog
    Feb 22, 2021 at 21:17

2 Answers 2


One can use a timer to prevent keys from being pressed simultaneously. For example,

inoremap <C-a> <C-y><Esc>:call timer_start(100, {-> feedkeys("a ")})<CR>

will send <C-y><Esc> followed by a<Space> after 100ms.

Instead of 100ms, one can specify any delay, even 0ms.

Adding the above to the expr mapping for Space, we get

inoremap <expr><Space> pumvisible() && complete_info().selected != -1? '<C-y><Esc>:call timer_start(0, {-> feedkeys("a ")})<CR>' : '<Space>'

On my machine, this spits out the selected option, and after a tiny delay, adds a space.


The problem with your code is that in a mapping command, you do not need to escape <keys>. This is because they are already interpreted by the inoremap.

inoremap <expr><Space> pumvisible() && complete_info().selected != -1? '<C-y><Space>' : '<Space>'
  • You're right, they don't need escaping. However, using your example doesn't change the behaviour.
    – daedsidog
    Feb 23, 2021 at 0:36

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.