vim-patch:9.1.1160: Ctrl-Y does not work well with "preinsert" when completing items

Problem:  The 'preinsert' feature requires Ctrl-Y to confirm insertion,
          but Ctrl-Y only works when the popup menu (pum) is displayed.
          Without enforcing this dependency, it could lead to confusing
          behavior or non-functional features.

Solution: Modify ins_compl_has_preinsert() to check for both 'menu' and
          'menuone' flags when 'preinsert' is set. Update documentation
          to clarify this requirement. This avoids adding complex
          conditional behaviors. (glepnir)

fixes: vim/vim#16728
closes: vim/vim#16753

a2c5559f29

Co-authored-by: glepnir <glephunter@gmail.com>
This commit is contained in:
zeertzjq
2025-03-02 06:35:20 +08:00
parent 47b748af54
commit 26775183ff
6 changed files with 79 additions and 76 deletions

View File

@@ -1533,13 +1533,13 @@ A jump table for the options with a short description can be found at |Q_op|.
A comma-separated list of options for Insert mode completion A comma-separated list of options for Insert mode completion
|ins-completion|. The supported values are: |ins-completion|. The supported values are:
menu Use a popup menu to show the possible completions. The fuzzy Enable |fuzzy-matching| for completion candidates. This
menu is only shown when there is more than one match and allows for more flexible and intuitive matching, where
sufficient colors are available. |ins-completion-menu| characters can be skipped and matches can be found even
if the exact sequence is not typed. Only makes a
menuone Use the popup menu also when there is only one match. difference how completion candidates are reduced from the
Useful when there is additional information about the list of alternatives, but not how the candidates are
match, e.g., what file it comes from. collected (using different completion types).
longest Only insert the longest common text of the matches. If longest Only insert the longest common text of the matches. If
the menu is displayed you can use CTRL-L to add more the menu is displayed you can use CTRL-L to add more
@@ -1547,13 +1547,13 @@ A jump table for the options with a short description can be found at |Q_op|.
of completion. For buffer text the 'ignorecase' option is of completion. For buffer text the 'ignorecase' option is
used. used.
preview Show extra information about the currently selected menu Use a popup menu to show the possible completions. The
completion in the preview window. Only works in menu is only shown when there is more than one match and
combination with "menu" or "menuone". sufficient colors are available. |ins-completion-menu|
popup Show extra information about the currently selected menuone Use the popup menu also when there is only one match.
completion in a popup window. Only works in combination Useful when there is additional information about the
with "menu" or "menuone". Overrides "preview". match, e.g., what file it comes from.
noinsert Do not insert any text for a match until the user selects noinsert Do not insert any text for a match until the user selects
a match from the menu. Only works in combination with a match from the menu. Only works in combination with
@@ -1563,23 +1563,24 @@ A jump table for the options with a short description can be found at |Q_op|.
pre-selected. If both "noinsert" and "noselect" are pre-selected. If both "noinsert" and "noselect" are
present, "noselect" has precedence. present, "noselect" has precedence.
fuzzy Enable |fuzzy-matching| for completion candidates. This
allows for more flexible and intuitive matching, where
characters can be skipped and matches can be found even
if the exact sequence is not typed. Only makes a
difference how completion candidates are reduced from the
list of alternatives, but not how the candidates are
collected (using different completion types).
nosort Disable sorting of completion candidates based on fuzzy nosort Disable sorting of completion candidates based on fuzzy
scores when "fuzzy" is enabled. Candidates will appear scores when "fuzzy" is enabled. Candidates will appear
in their original order. in their original order.
popup Show extra information about the currently selected
completion in a popup window. Only works in combination
with "menu" or "menuone". Overrides "preview".
preinsert preinsert
Preinsert the portion of the first candidate word that is Preinsert the portion of the first candidate word that is
not part of the current completion leader and using the not part of the current completion leader and using the
|hl-ComplMatchIns| highlight group. Does not work when |hl-ComplMatchIns| highlight group. Does not work when
"fuzzy" is also included. "fuzzy" is set. Requires both "menu" and "menuone" to be
set.
preview Show extra information about the currently selected
completion in the preview window. Only works in
combination with "menu" or "menuone".
*'completeslash'* *'csl'* *'completeslash'* *'csl'*
'completeslash' 'csl' string (default "") 'completeslash' 'csl' string (default "")

View File

@@ -1060,13 +1060,13 @@ vim.go.cia = vim.go.completeitemalign
--- A comma-separated list of options for Insert mode completion --- A comma-separated list of options for Insert mode completion
--- `ins-completion`. The supported values are: --- `ins-completion`. The supported values are:
--- ---
--- menu Use a popup menu to show the possible completions. The --- fuzzy Enable `fuzzy-matching` for completion candidates. This
--- menu is only shown when there is more than one match and --- allows for more flexible and intuitive matching, where
--- sufficient colors are available. `ins-completion-menu` --- characters can be skipped and matches can be found even
--- --- if the exact sequence is not typed. Only makes a
--- menuone Use the popup menu also when there is only one match. --- difference how completion candidates are reduced from the
--- Useful when there is additional information about the --- list of alternatives, but not how the candidates are
--- match, e.g., what file it comes from. --- collected (using different completion types).
--- ---
--- longest Only insert the longest common text of the matches. If --- longest Only insert the longest common text of the matches. If
--- the menu is displayed you can use CTRL-L to add more --- the menu is displayed you can use CTRL-L to add more
@@ -1074,13 +1074,13 @@ vim.go.cia = vim.go.completeitemalign
--- of completion. For buffer text the 'ignorecase' option is --- of completion. For buffer text the 'ignorecase' option is
--- used. --- used.
--- ---
--- preview Show extra information about the currently selected --- menu Use a popup menu to show the possible completions. The
--- completion in the preview window. Only works in --- menu is only shown when there is more than one match and
--- combination with "menu" or "menuone". --- sufficient colors are available. `ins-completion-menu`
--- ---
--- popup Show extra information about the currently selected --- menuone Use the popup menu also when there is only one match.
--- completion in a popup window. Only works in combination --- Useful when there is additional information about the
--- with "menu" or "menuone". Overrides "preview". --- match, e.g., what file it comes from.
--- ---
--- noinsert Do not insert any text for a match until the user selects --- noinsert Do not insert any text for a match until the user selects
--- a match from the menu. Only works in combination with --- a match from the menu. Only works in combination with
@@ -1090,23 +1090,24 @@ vim.go.cia = vim.go.completeitemalign
--- pre-selected. If both "noinsert" and "noselect" are --- pre-selected. If both "noinsert" and "noselect" are
--- present, "noselect" has precedence. --- present, "noselect" has precedence.
--- ---
--- fuzzy Enable `fuzzy-matching` for completion candidates. This
--- allows for more flexible and intuitive matching, where
--- characters can be skipped and matches can be found even
--- if the exact sequence is not typed. Only makes a
--- difference how completion candidates are reduced from the
--- list of alternatives, but not how the candidates are
--- collected (using different completion types).
---
--- nosort Disable sorting of completion candidates based on fuzzy --- nosort Disable sorting of completion candidates based on fuzzy
--- scores when "fuzzy" is enabled. Candidates will appear --- scores when "fuzzy" is enabled. Candidates will appear
--- in their original order. --- in their original order.
--- ---
--- popup Show extra information about the currently selected
--- completion in a popup window. Only works in combination
--- with "menu" or "menuone". Overrides "preview".
---
--- preinsert --- preinsert
--- Preinsert the portion of the first candidate word that is --- Preinsert the portion of the first candidate word that is
--- not part of the current completion leader and using the --- not part of the current completion leader and using the
--- `hl-ComplMatchIns` highlight group. Does not work when --- `hl-ComplMatchIns` highlight group. Does not work when
--- "fuzzy" is also included. --- "fuzzy" is set. Requires both "menu" and "menuone" to be
--- set.
---
--- preview Show extra information about the currently selected
--- completion in the preview window. Only works in
--- combination with "menu" or "menuone".
--- ---
--- @type string --- @type string
vim.o.completeopt = "menu,preview" vim.o.completeopt = "menu,preview"

View File

@@ -563,10 +563,8 @@ static int insert_execute(VimState *state, int key)
// Special handling of keys while the popup menu is visible or wanted // Special handling of keys while the popup menu is visible or wanted
// and the cursor is still in the completed word. Only when there is // and the cursor is still in the completed word. Only when there is
// a match, skip this when no matches were found. // a match, skip this when no matches were found.
bool ins_completion = ins_compl_active() if (ins_compl_active() && curwin->w_cursor.col >= ins_compl_col()
&& curwin->w_cursor.col >= ins_compl_col() && ins_compl_has_shown_match() && pum_wanted()) {
&& ins_compl_has_shown_match();
if (ins_completion && pum_wanted()) {
// BS: Delete one character from "compl_leader". // BS: Delete one character from "compl_leader".
if ((s->c == K_BS || s->c == Ctrl_H) if ((s->c == K_BS || s->c == Ctrl_H)
&& curwin->w_cursor.col > ins_compl_col() && curwin->w_cursor.col > ins_compl_col()
@@ -616,8 +614,6 @@ static int insert_execute(VimState *state, int key)
ins_compl_delete(false); ins_compl_delete(false);
} }
} }
} else if (ins_completion && !pum_wanted() && ins_compl_preinsert_effect()) {
ins_compl_delete(false);
} }
// Prepare for or stop CTRL-X mode. This doesn't do completion, but it does // Prepare for or stop CTRL-X mode. This doesn't do completion, but it does

View File

@@ -1808,10 +1808,13 @@ int ins_compl_len(void)
return compl_length; return compl_length;
} }
/// Return true when preinsert is set otherwise FALSE. /// Return TRUE when preinsert is set AND both 'menu' and 'menuone' flags
/// are also set, otherwise return FALSE.
static bool ins_compl_has_preinsert(void) static bool ins_compl_has_preinsert(void)
{ {
return (get_cot_flags() & (kOptCotFlagFuzzy|kOptCotFlagPreinsert)) == kOptCotFlagPreinsert; return (get_cot_flags()
& (kOptCotFlagFuzzy|kOptCotFlagPreinsert|kOptCotFlagMenu|kOptCotFlagMenuone))
== (kOptCotFlagPreinsert|kOptCotFlagMenu|kOptCotFlagMenuone);
} }
/// Returns true if the pre-insert effect is valid and the cursor is within /// Returns true if the pre-insert effect is valid and the cursor is within

View File

@@ -1502,13 +1502,13 @@ local options = {
A comma-separated list of options for Insert mode completion A comma-separated list of options for Insert mode completion
|ins-completion|. The supported values are: |ins-completion|. The supported values are:
menu Use a popup menu to show the possible completions. The fuzzy Enable |fuzzy-matching| for completion candidates. This
menu is only shown when there is more than one match and allows for more flexible and intuitive matching, where
sufficient colors are available. |ins-completion-menu| characters can be skipped and matches can be found even
if the exact sequence is not typed. Only makes a
menuone Use the popup menu also when there is only one match. difference how completion candidates are reduced from the
Useful when there is additional information about the list of alternatives, but not how the candidates are
match, e.g., what file it comes from. collected (using different completion types).
longest Only insert the longest common text of the matches. If longest Only insert the longest common text of the matches. If
the menu is displayed you can use CTRL-L to add more the menu is displayed you can use CTRL-L to add more
@@ -1516,13 +1516,13 @@ local options = {
of completion. For buffer text the 'ignorecase' option is of completion. For buffer text the 'ignorecase' option is
used. used.
preview Show extra information about the currently selected menu Use a popup menu to show the possible completions. The
completion in the preview window. Only works in menu is only shown when there is more than one match and
combination with "menu" or "menuone". sufficient colors are available. |ins-completion-menu|
popup Show extra information about the currently selected menuone Use the popup menu also when there is only one match.
completion in a popup window. Only works in combination Useful when there is additional information about the
with "menu" or "menuone". Overrides "preview". match, e.g., what file it comes from.
noinsert Do not insert any text for a match until the user selects noinsert Do not insert any text for a match until the user selects
a match from the menu. Only works in combination with a match from the menu. Only works in combination with
@@ -1532,23 +1532,24 @@ local options = {
pre-selected. If both "noinsert" and "noselect" are pre-selected. If both "noinsert" and "noselect" are
present, "noselect" has precedence. present, "noselect" has precedence.
fuzzy Enable |fuzzy-matching| for completion candidates. This
allows for more flexible and intuitive matching, where
characters can be skipped and matches can be found even
if the exact sequence is not typed. Only makes a
difference how completion candidates are reduced from the
list of alternatives, but not how the candidates are
collected (using different completion types).
nosort Disable sorting of completion candidates based on fuzzy nosort Disable sorting of completion candidates based on fuzzy
scores when "fuzzy" is enabled. Candidates will appear scores when "fuzzy" is enabled. Candidates will appear
in their original order. in their original order.
popup Show extra information about the currently selected
completion in a popup window. Only works in combination
with "menu" or "menuone". Overrides "preview".
preinsert preinsert
Preinsert the portion of the first candidate word that is Preinsert the portion of the first candidate word that is
not part of the current completion leader and using the not part of the current completion leader and using the
|hl-ComplMatchIns| highlight group. Does not work when |hl-ComplMatchIns| highlight group. Does not work when
"fuzzy" is also included. "fuzzy" is set. Requires both "menu" and "menuone" to be
set.
preview Show extra information about the currently selected
completion in the preview window. Only works in
combination with "menu" or "menuone".
]=], ]=],
full_name = 'completeopt', full_name = 'completeopt',
list = 'onecomma', list = 'onecomma',

View File

@@ -3110,10 +3110,11 @@ function Test_completeopt_preinsert()
call assert_equal("fobar", getline('.')) call assert_equal("fobar", getline('.'))
call assert_equal(5, col('.')) call assert_equal(5, col('.'))
" When the pum is not visible, the preinsert has no effect
set cot=preinsert set cot=preinsert
call feedkeys("Sfoo1 foo2\<CR>f\<C-X>\<C-N>bar", 'tx') call feedkeys("Sfoo1 foo2\<CR>f\<C-X>\<C-N>bar", 'tx')
call assert_equal("fbar", getline('.')) call assert_equal("foo1bar", getline('.'))
call assert_equal(4, col('.')) call assert_equal(7, col('.'))
bw! bw!
set cot& set cot&