patch 9.1.0896: completion list wrong after v9.1.0891
Problem: completion list wrong after v9.1.0891
Solution: update compl_mach_array after leader change
(glepnir)
compl_shown_match update not correct after refactoring in v9.1.0891
Unfortunately, this regressed what item is selected after leader change.
So generate compl_match_array before updating compl_shown_match range,
and split generate compl_match_array into range match_head
fixes: #16128
closes: #16129
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/insexpand.c b/src/insexpand.c
index ba5f919..75403f1 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -1228,7 +1228,7 @@
compl_T *shown_compl = NULL;
int did_find_shown_match = FALSE;
int shown_match_ok = FALSE;
- int i;
+ int i = 0;
int cur = -1;
int max_fuzzy_score = 0;
unsigned int cur_cot_flags = get_cot_flags();
@@ -1242,6 +1242,17 @@
compl_match_arraysize = 0;
compl = compl_first_match;
+ // If the current match is the original text don't find the first
+ // match after it, don't highlight anything.
+ if (match_at_original_text(compl_shown_match))
+ shown_match_ok = TRUE;
+
+ if (compl_leader.string != NULL
+ && STRCMP(compl_leader.string, compl_orig_text.string) == 0
+ && shown_match_ok == FALSE)
+ compl_shown_match = compl_no_select ? compl_first_match
+ : compl_first_match->cp_next;
+
do
{
// When 'completeopt' contains "fuzzy" and leader is not NULL or empty,
@@ -1258,98 +1269,47 @@
if (match_head == NULL)
match_head = compl;
else
- match_tail->cp_match_next = compl;
+ match_tail->cp_match_next = compl;
match_tail = compl;
+
+ if (!shown_match_ok && !compl_fuzzy_match)
+ {
+ if (compl == compl_shown_match || did_find_shown_match)
+ {
+ // This item is the shown match or this is the
+ // first displayed item after the shown match.
+ compl_shown_match = compl;
+ did_find_shown_match = TRUE;
+ shown_match_ok = TRUE;
+ }
+ else
+ // Remember this displayed match for when the
+ // shown match is just below it.
+ shown_compl = compl;
+ cur = i;
+ }
+ else if (compl_fuzzy_match)
+ {
+ if (i == 0)
+ shown_compl = compl;
+ // Update the maximum fuzzy score and the shown match
+ // if the current item's score is higher
+ if (compl->cp_score > max_fuzzy_score)
+ {
+ did_find_shown_match = TRUE;
+ max_fuzzy_score = compl->cp_score;
+ if (!compl_no_select)
+ compl_shown_match = compl;
+ }
+
+ if (!shown_match_ok && compl == compl_shown_match && !compl_no_select)
+ {
+ cur = i;
+ shown_match_ok = TRUE;
+ }
+ }
+ i++;
}
- compl = compl->cp_next;
- } while (compl != NULL && !is_first_match(compl));
-
- if (compl_match_arraysize == 0)
- return -1;
-
- compl_match_array = ALLOC_CLEAR_MULT(pumitem_T, compl_match_arraysize);
- if (compl_match_array == NULL)
- return -1;
-
- // If the current match is the original text don't find the first
- // match after it, don't highlight anything.
- if (match_at_original_text(compl_shown_match))
- shown_match_ok = TRUE;
-
- if (compl_leader.string != NULL
- && STRCMP(compl_leader.string, compl_orig_text.string) == 0
- && shown_match_ok == FALSE)
- compl_shown_match = compl_no_select ? compl_first_match
- : compl_first_match->cp_next;
- i = 0;
- compl = match_head;
- if (match_tail == match_head)
- did_find_shown_match = TRUE;
- while (compl != NULL)
- {
- if (!shown_match_ok && !compl_fuzzy_match)
- {
- if (compl == compl_shown_match || did_find_shown_match)
- {
- // This item is the shown match or this is the
- // first displayed item after the shown match.
- compl_shown_match = compl;
- did_find_shown_match = TRUE;
- shown_match_ok = TRUE;
- }
- else
- // Remember this displayed match for when the
- // shown match is just below it.
- shown_compl = compl;
- cur = i;
- }
- else if (compl_fuzzy_match)
- {
- if (i == 0)
- shown_compl = compl;
- // Update the maximum fuzzy score and the shown match
- // if the current item's score is higher
- if (compl->cp_score > max_fuzzy_score)
- {
- did_find_shown_match = TRUE;
- max_fuzzy_score = compl->cp_score;
- if (!compl_no_select)
- compl_shown_match = compl;
- }
-
- if (!shown_match_ok && compl == compl_shown_match && !compl_no_select)
- {
- cur = i;
- shown_match_ok = TRUE;
- }
-
- // If there is no "no select" condition and the max fuzzy
- // score is positive, or there is no completion leader or the
- // leader length is zero, mark the shown match as valid and
- // reset the current index.
- if (!compl_no_select
- && (max_fuzzy_score > 0
- || (compl_leader.string == NULL || compl_leader.length == 0)))
- {
- if (match_at_original_text(compl_shown_match))
- compl_shown_match = shown_compl;
- }
- }
-
- if (compl->cp_text[CPT_ABBR] != NULL)
- compl_match_array[i].pum_text = compl->cp_text[CPT_ABBR];
- else
- compl_match_array[i].pum_text = compl->cp_str.string;
- compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND];
- compl_match_array[i].pum_info = compl->cp_text[CPT_INFO];
- compl_match_array[i].pum_score = compl->cp_score;
- compl_match_array[i].pum_user_abbr_hlattr = compl->cp_user_abbr_hlattr;
- compl_match_array[i].pum_user_kind_hlattr = compl->cp_user_kind_hlattr;
- if (compl->cp_text[CPT_MENU] != NULL)
- compl_match_array[i++].pum_extra =
- compl->cp_text[CPT_MENU];
- else
- compl_match_array[i++].pum_extra = compl->cp_fname;
if (compl == compl_shown_match && !compl_fuzzy_match)
{
@@ -1368,6 +1328,34 @@
shown_match_ok = TRUE;
}
}
+ compl = compl->cp_next;
+ } while (compl != NULL && !is_first_match(compl));
+
+ if (compl_match_arraysize == 0)
+ return -1;
+
+ compl_match_array = ALLOC_CLEAR_MULT(pumitem_T, compl_match_arraysize);
+ if (compl_match_array == NULL)
+ return -1;
+
+ compl = match_head;
+ i = 0;
+ while (compl != NULL)
+ {
+ if (compl->cp_text[CPT_ABBR] != NULL)
+ compl_match_array[i].pum_text = compl->cp_text[CPT_ABBR];
+ else
+ compl_match_array[i].pum_text = compl->cp_str.string;
+ compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND];
+ compl_match_array[i].pum_info = compl->cp_text[CPT_INFO];
+ compl_match_array[i].pum_score = compl->cp_score;
+ compl_match_array[i].pum_user_abbr_hlattr = compl->cp_user_abbr_hlattr;
+ compl_match_array[i].pum_user_kind_hlattr = compl->cp_user_kind_hlattr;
+ if (compl->cp_text[CPT_MENU] != NULL)
+ compl_match_array[i++].pum_extra =
+ compl->cp_text[CPT_MENU];
+ else
+ compl_match_array[i++].pum_extra = compl->cp_fname;
match_next = compl->cp_match_next;
compl->cp_match_next = NULL;
compl = match_next;
diff --git a/src/testdir/dumps/Test_pum_keep_select_01.dump b/src/testdir/dumps/Test_pum_keep_select_01.dump
new file mode 100644
index 0000000..42877d0
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_keep_select_01.dump
@@ -0,0 +1,20 @@
+|F+0&#ffffff0|a|b| @71
+|F|i|v|e| @70
+|f|i|n|d| @70
+|f|i|l|m| @70
+> @74
+|F+0#0000001#ffd7ff255|a|b| @11| +0#4040ff13#ffffff0@59
+|F+0#0000001#ffd7ff255|i|v|e| @10| +0#4040ff13#ffffff0@59
+|f+0#0000001#ffd7ff255|i|n|d| @10| +0#4040ff13#ffffff0@59
+|f+0#0000001#e0e0e08|i|l|m| @10| +0#4040ff13#ffffff0@59
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |4| +0#0000000&@27
diff --git a/src/testdir/dumps/Test_pum_keep_select_02.dump b/src/testdir/dumps/Test_pum_keep_select_02.dump
new file mode 100644
index 0000000..c4dbb27
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_keep_select_02.dump
@@ -0,0 +1,20 @@
+|F+0&#ffffff0|a|b| @71
+|F|i|v|e| @70
+|f|i|n|d| @70
+|f|i|l|m| @70
+|F> @73
+|F+0#0000001#ffd7ff255|a|b| @11| +0#4040ff13#ffffff0@59
+|F+0#0000001#e0e0e08|i|v|e| @10| +0#4040ff13#ffffff0@59
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |4| +0#0000000&@27
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
index 6b807c8..d5e6e31 100644
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -1673,4 +1673,29 @@
call StopVimInTerminal(buf)
endfunc
+func Test_pum_keep_select()
+ CheckScreendump
+ let lines =<< trim END
+ set completeopt=menu,menuone,noinsert
+ END
+ call writefile(lines, 'Xscript', 'D')
+ let buf = RunVimInTerminal('-S Xscript', {})
+ call TermWait(buf)
+
+ call term_sendkeys(buf, "ggSFab\<CR>Five\<CR>find\<CR>film\<CR>\<C-X>\<C-P>")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_pum_keep_select_01', {})
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+ call TermWait(buf, 50)
+
+ call term_sendkeys(buf, "S\<C-X>\<C-P>")
+ call TermWait(buf, 50)
+ call term_sendkeys(buf, "F")
+ call VerifyScreenDump(buf, 'Test_pum_keep_select_02', {})
+ call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+ call TermWait(buf, 50)
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 325788c..e1f8489 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 896,
+/**/
895,
/**/
894,