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
|ins-completion|. The supported values are:
menu Use a popup menu to show the possible completions. The
menu is only shown when there is more than one match and
sufficient colors are available. |ins-completion-menu|
menuone Use the popup menu also when there is only one match.
Useful when there is additional information about the
match, e.g., what file it comes from.
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).
longest Only insert the longest common text of the matches. If
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
used.
preview Show extra information about the currently selected
completion in the preview window. Only works in
combination with "menu" or "menuone".
menu Use a popup menu to show the possible completions. The
menu is only shown when there is more than one match and
sufficient colors are available. |ins-completion-menu|
popup Show extra information about the currently selected
completion in a popup window. Only works in combination
with "menu" or "menuone". Overrides "preview".
menuone Use the popup menu also when there is only one match.
Useful when there is additional information about the
match, e.g., what file it comes from.
noinsert Do not insert any text for a match until the user selects
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
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
scores when "fuzzy" is enabled. Candidates will appear
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 the portion of the first candidate word that is
not part of the current completion leader and using the
|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' string (default "")

View File

@ -1060,13 +1060,13 @@ vim.go.cia = vim.go.completeitemalign
--- A comma-separated list of options for Insert mode completion
--- `ins-completion`. The supported values are:
---
--- menu Use a popup menu to show the possible completions. The
--- menu is only shown when there is more than one match and
--- sufficient colors are available. `ins-completion-menu`
---
--- menuone Use the popup menu also when there is only one match.
--- Useful when there is additional information about the
--- match, e.g., what file it comes from.
--- 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).
---
--- longest Only insert the longest common text of the matches. If
--- 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
--- used.
---
--- preview Show extra information about the currently selected
--- completion in the preview window. Only works in
--- combination with "menu" or "menuone".
--- menu Use a popup menu to show the possible completions. The
--- menu is only shown when there is more than one match and
--- sufficient colors are available. `ins-completion-menu`
---
--- popup Show extra information about the currently selected
--- completion in a popup window. Only works in combination
--- with "menu" or "menuone". Overrides "preview".
--- menuone Use the popup menu also when there is only one match.
--- Useful when there is additional information about the
--- match, e.g., what file it comes from.
---
--- noinsert Do not insert any text for a match until the user selects
--- 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
--- 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
--- scores when "fuzzy" is enabled. Candidates will appear
--- 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 the portion of the first candidate word that is
--- not part of the current completion leader and using the
--- `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
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
// and the cursor is still in the completed word. Only when there is
// a match, skip this when no matches were found.
bool ins_completion = ins_compl_active()
&& curwin->w_cursor.col >= ins_compl_col()
&& ins_compl_has_shown_match();
if (ins_completion && pum_wanted()) {
if (ins_compl_active() && curwin->w_cursor.col >= ins_compl_col()
&& ins_compl_has_shown_match() && pum_wanted()) {
// BS: Delete one character from "compl_leader".
if ((s->c == K_BS || s->c == Ctrl_H)
&& curwin->w_cursor.col > ins_compl_col()
@ -616,8 +614,6 @@ static int insert_execute(VimState *state, int key)
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

View File

@ -1808,10 +1808,13 @@ int ins_compl_len(void)
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)
{
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

View File

@ -1502,13 +1502,13 @@ local options = {
A comma-separated list of options for Insert mode completion
|ins-completion|. The supported values are:
menu Use a popup menu to show the possible completions. The
menu is only shown when there is more than one match and
sufficient colors are available. |ins-completion-menu|
menuone Use the popup menu also when there is only one match.
Useful when there is additional information about the
match, e.g., what file it comes from.
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).
longest Only insert the longest common text of the matches. If
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
used.
preview Show extra information about the currently selected
completion in the preview window. Only works in
combination with "menu" or "menuone".
menu Use a popup menu to show the possible completions. The
menu is only shown when there is more than one match and
sufficient colors are available. |ins-completion-menu|
popup Show extra information about the currently selected
completion in a popup window. Only works in combination
with "menu" or "menuone". Overrides "preview".
menuone Use the popup menu also when there is only one match.
Useful when there is additional information about the
match, e.g., what file it comes from.
noinsert Do not insert any text for a match until the user selects
a match from the menu. Only works in combination with
@ -1532,23 +1532,24 @@ local options = {
pre-selected. If both "noinsert" and "noselect" are
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
scores when "fuzzy" is enabled. Candidates will appear
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 the portion of the first candidate word that is
not part of the current completion leader and using the
|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',
list = 'onecomma',

View File

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