Emulating Vim's <c-p>/<c-n>: autocomplete to exact match near cursor

In vim’s insert mode, the autocompletion list only has exact matches, and they are sorted by distance to the cursor. <c-p> lists all words before the cursor that match, starting with the word closest to the cursor, while <c-n> lists all words after the cursor that match, again starting with the word closest the cursor.

This makes vim’s autocomplete work very well for inserting a word that already appears near the cursor. For example, if I want to type:

my_variable = foo(my_variable);

then to type the second my_variable, I can just press m<c-p>. Since my_variable is the first word before the cursor that begins with m, I know I have to press <c-p> exactly once without even looking at the completion list. This is very fast.

Kakoune’s autocompletion on the other hand is fuzzy, increasing the number of matches, and matches are not sorted by distance to the cursor (Kakoune may even show matches from other buffers before matches from the current buffer - you must use <c-x>w to only use the current buffer).

This makes autocompleting a word that appears near the cursor much slower than in vim. I need to type many characters to narrow down the list, and I don’t know beforehand how many characters I’ll need to write and how many times I’ll need to press <c-n>.

So I wrote the following mappings to emulate vim’s <c-p>/<c-n>:

define-command -hidden -override autocomplete-to-exact-match-before-cursor %{
    execute-keys -draft -save-regs 'a/"^' 'h[wZ"a<a-*><a-/>\b<c-r>a<ret><a-:>EyzR'
}

define-command -hidden -override autocomplete-to-exact-match-after-cursor %{
    execute-keys -draft -save-regs 'a/"^' 'h[wZ"a<a-*>/\b<c-r>a<ret><a-:>EyzR'
}

map global insert '<a-p>' '<a-;>: autocomplete-to-exact-match-before-cursor<ret>'
map global insert '<a-n>' '<a-;>: autocomplete-to-exact-match-after-cursor<ret>'

They autocomplete the current word into the first match that would be suggested by vim’s <c-p>/<c-n>.

This can probably be improved by making these mappings additionally change Kakoune’s autocompletion list to the list vim would show, but the first match is usually right.

2 Likes