diff --git a/src/insexpand.c b/src/insexpand.c index ba5f919a9b..75403f1b3b 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -1228,7 +1228,7 @@ ins_compl_build_pum(void) 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 @@ ins_compl_build_pum(void) 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 @@ ins_compl_build_pum(void) 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 @@ ins_compl_build_pum(void) 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 0000000000..42877d04ae --- /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 0000000000..c4dbb27a6a --- /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 6b807c8c3e..d5e6e312a0 100644 --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -1673,4 +1673,29 @@ func Test_pum_completeitemalign() 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\Five\find\film\\\") + call TermWait(buf, 50) + call VerifyScreenDump(buf, 'Test_pum_keep_select_01', {}) + call term_sendkeys(buf, "\\") + call TermWait(buf, 50) + + call term_sendkeys(buf, "S\\") + call TermWait(buf, 50) + call term_sendkeys(buf, "F") + call VerifyScreenDump(buf, 'Test_pum_keep_select_02', {}) + call term_sendkeys(buf, "\\") + + 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 325788c8cc..e1f8489cb5 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 896, /**/ 895, /**/