# HG changeset patch # User Bram Moolenaar # Date 1603737004 -3600 # Node ID bd61aaf7f2a02b674e79fd5df7a0b36a782e39d0 # Parent 071666f3558bcd7c24764b47c96ed9ef1476a0c5 patch 8.2.1907: complete_info().selected may be wrong Commit: https://github.com/vim/vim/commit/f9d51354de069dddc049b9e109b1932c92e5aee6 Author: Bram Moolenaar Date: Mon Oct 26 19:22:42 2020 +0100 patch 8.2.1907: complete_info().selected may be wrong Problem: Complete_info().selected may be wrong. Solution: Update cp_number if it was never set. (issue https://github.com/vim/vim/issues/6945) diff --git a/src/insexpand.c b/src/insexpand.c --- a/src/insexpand.c +++ b/src/insexpand.c @@ -2498,6 +2498,56 @@ ins_compl_mode(void) return (char_u *)""; } + static void +ins_compl_update_sequence_numbers() +{ + int number = 0; + compl_T *match; + + if (compl_direction == FORWARD) + { + // search backwards for the first valid (!= -1) number. + // This should normally succeed already at the first loop + // cycle, so it's fast! + for (match = compl_curr_match->cp_prev; match != NULL + && match != compl_first_match; + match = match->cp_prev) + if (match->cp_number != -1) + { + number = match->cp_number; + break; + } + if (match != NULL) + // go up and assign all numbers which are not assigned + // yet + for (match = match->cp_next; + match != NULL && match->cp_number == -1; + match = match->cp_next) + match->cp_number = ++number; + } + else // BACKWARD + { + // search forwards (upwards) for the first valid (!= -1) + // number. This should normally succeed already at the + // first loop cycle, so it's fast! + for (match = compl_curr_match->cp_next; match != NULL + && match != compl_first_match; + match = match->cp_next) + if (match->cp_number != -1) + { + number = match->cp_number; + break; + } + if (match != NULL) + // go down and assign all numbers which are not + // assigned yet + for (match = match->cp_prev; match + && match->cp_number == -1; + match = match->cp_prev) + match->cp_number = ++number; + } +} + /* * Get complete information */ @@ -2584,8 +2634,12 @@ get_complete_info(list_T *what_list, dic } if (ret == OK && (what_flag & CI_WHAT_SELECTED)) - ret = dict_add_number(retdict, "selected", (compl_curr_match != NULL) ? - compl_curr_match->cp_number - 1 : -1); + { + if (compl_curr_match != NULL && compl_curr_match->cp_number == -1) + ins_compl_update_sequence_numbers(); + ret = dict_add_number(retdict, "selected", compl_curr_match != NULL + ? compl_curr_match->cp_number - 1 : -1); + } // TODO // if (ret == OK && (what_flag & CI_WHAT_INSERTED)) @@ -4009,59 +4063,13 @@ ins_complete(int c, int enable_pum) { edit_submode_extra = (char_u *)_("The only match"); edit_submode_highl = HLF_COUNT; - compl_curr_match->cp_number = 0; + compl_curr_match->cp_number = 1; } else { // Update completion sequence number when needed. if (compl_curr_match->cp_number == -1) - { - int number = 0; - compl_T *match; - - if (compl_direction == FORWARD) - { - // search backwards for the first valid (!= -1) number. - // This should normally succeed already at the first loop - // cycle, so it's fast! - for (match = compl_curr_match->cp_prev; match != NULL - && match != compl_first_match; - match = match->cp_prev) - if (match->cp_number != -1) - { - number = match->cp_number; - break; - } - if (match != NULL) - // go up and assign all numbers which are not assigned - // yet - for (match = match->cp_next; - match != NULL && match->cp_number == -1; - match = match->cp_next) - match->cp_number = ++number; - } - else // BACKWARD - { - // search forwards (upwards) for the first valid (!= -1) - // number. This should normally succeed already at the - // first loop cycle, so it's fast! - for (match = compl_curr_match->cp_next; match != NULL - && match != compl_first_match; - match = match->cp_next) - if (match->cp_number != -1) - { - number = match->cp_number; - break; - } - if (match != NULL) - // go down and assign all numbers which are not - // assigned yet - for (match = match->cp_prev; match - && match->cp_number == -1; - match = match->cp_prev) - match->cp_number = ++number; - } - } + ins_compl_update_sequence_numbers(); // The match should always have a sequence number now, this is // just a safety check. diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim --- a/src/testdir/test_ins_complete.vim +++ b/src/testdir/test_ins_complete.vim @@ -325,7 +325,7 @@ func Test_completefunc_info() set completeopt=menuone set completefunc=CompleteTest call feedkeys("i\\\\=string(complete_info())\\", "tx") - call assert_equal("matched{'pum_visible': 1, 'mode': 'function', 'selected': -1, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1)) + call assert_equal("matched{'pum_visible': 1, 'mode': 'function', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1)) bwipe! set completeopt& set completefunc& diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1907, +/**/ 1906, /**/ 1905,