I’ve been using vim-closer for a while as a lightweight parenthesis/bracket closing plugin. I like it because it only fires when I hit enter, and it’s pretty lightweight and non-invasive.
Recently, I switched my code-completion setup to
, but was frustrated that Go’s
gopls preselect puts vim’s completion pop-up menu into the “selected” state,
which takes over the behavior of the enter key to accept the selection (c.f.
menu completion state
Here’s an example:
If preselect is on at the end of a line like in the picture above, hitting
enter doesn’t give a new line – it only accepts the completion suggestion.
To get a newline in this situation, I have to hit enter twice. And
preselection happens for a lot of simple keywords I can type just fine without
nil or basic types in struct definitions:
There are examples
<CR> key to always accept the text if the pop-up is visible.
Here is one of them:
inoremap <expr> <CR> pumvisible() ? "\<C-Y>" : "\<CR>"
I wanted the opposite: stop the match on
<CR> and put in the newline:
inoremap <expr> <CR> pumvisible() ? "\<C-E>\<CR>" : "\<CR>"
But when I tried to remap the
<CR> key this way, everything went kablooey.
Literally. My editor froze until I hit
CTRL-C, and ‘
pumvisible() ? ...’ was
spammed hundreds of times into my buffer.
The problem was that
<CR> on a per-buffer basis – trying
to extend any existing mapping – and that fails badly with the
pumvisible. From suggestions on an
figured out a solution.
I moved the expression logic into a function that gets called from the mapping
<C-R>=...<CR> sequence (a.k.a. the expression
function! HandleCRKey() abort return pumvisible() ? "\<C-E>\n" : "\n" endfunction inoremap <silent> <CR> <C-R>=HandleCRKey()<CR>
Because this doesn’t use an
vim-closer can extend the
mapping correctly when loading a buffer and I get both completion mapping the
way I want and the bracket closing I like.
I hope this helps anyone else trying to combine
pumvisible expressions with