Closed lacygoill closed 7 years ago
Here's a gif showing what happens when 'cot'
contains noselect
:
And here's what happens when 'cot'
doesn't contain noselect
, but does contain noinsert
:
In the first case, the repetition with the dot command is only partial. In the second case, it's complete.
I think that the problem is that, after pressing a cursor key, Vim in “state 2” (:h ins-completion-menu
), that is, it considers the match as not inserted. I don't know whether the fact that the text is there, and it stays there after pressing <esc>
is by design.
It might make sense to ignore noselect
in manual completion, which would solve this problem.
I agree with you (ignoring noselect
), that's what I do anyway, I don't add noselect
because of this. noinsert
is enough.
Besides, it would make the code inside s:act_on_pumvisible()
simpler.
Hello,
If I write the following text inside
/tmp/vimrc.vim
:And then if I run Vim from the shell like this:
I put the cursor on the word
world
and hit*
to populate the search register. I hitcgn
to change the next occurrence of the search register (hereworld
). I insertpe
and hit Tab to complete. The plugin insertspeople_A
, and the menu suggestspeople_A
,people_B
andpeople_C
. It doesn't select any entry, respecting the valuenoselect
.If I then hit escape to go back to normal mode, then the dot command to repeat the last change, the next occurrence of
world
is replaced withpe
instead ofpeople_A
like I expected.The problem comes from the function
s:act_on_pumvisible()
, and more specifically from this line:Its purpose is to hit
C-n Up
after the pop-up menu has been opened, if'completeopt'
contains the value'noselect'
, in order to force the insertion of the first or last entry from the menu.I think the keys
<Up>
and<Down>
are special, insofar as they break the undo sequence, as described in:h ins-special-special
. Breaking the undo sequence means that the dot register discards the text that was inserted so far, and records only from the current point. It can be checked in the current case by looking at the output of:reg.
.Usually, when you want the dot command to repeat the last edit entirely, and it contains a special key, you prefix the latter with
C-g U
which preserves the undo sequence (see:h i_^gU
). But here it doesn't seem to work. HittingC-g
makes us leave the pop-up menu.I must admit I don't really understand the bug, for 2 different reasons. First, if
<Up>
or<Down>
break the undo sequence, then, in the last example, the dot command shouldn't repeatpe
butople_A
. Second, why do they break the undo sequence, when'completeopt'
contains the valuenoselect
ands:act_on_pumvisible()
hitC-n Up
, but they don't seem to break it when'completeopt'
does NOT containnoselect
but DOES containnoinsert
ands:act_on_pumvisible()
hitUp C-n
?To be clear, this isn't a bug in the plugin. It seems to be a standard behavior from Vim, but I don't understand it. And it causes the plugin to break the undo sequence when
'completeopt'
containsnoselect
. I don't know if it deserves a fix, and if it does, I have no idea how to write one.You could replace
C-n Up
andC-p Down
with simplyC-n
andC-p
. It would preserve the undo sequence, but it wouldn't respect the user settingset completeopt+=noselect
, because then an entry from the menu would be selected, regardless of the option's value.