]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.1907: complete_info().selected may be wrong v8.2.1907
authorBram Moolenaar <Bram@vim.org>
Mon, 26 Oct 2020 18:22:42 +0000 (19:22 +0100)
committerBram Moolenaar <Bram@vim.org>
Mon, 26 Oct 2020 18:22:42 +0000 (19:22 +0100)
Problem:    Complete_info().selected may be wrong.
Solution:   Update cp_number if it was never set. (issue #6945)

src/insexpand.c
src/testdir/test_ins_complete.vim
src/version.c

index 23ab0afc0ae187d41ff49184e109271fc5b63bf6..a0aa1024ac2b769431c2352ba3caa93002a0fcd0 100644 (file)
@@ -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, dict_T *retdict)
     }
 
     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.
index 8c676e22a97d22c4dad4085d91aec06b33e0d181..5e2bebbf54f0b68e67e974441faca7b28a680c00 100644 (file)
@@ -325,7 +325,7 @@ func Test_completefunc_info()
   set completeopt=menuone
   set completefunc=CompleteTest
   call feedkeys("i\<C-X>\<C-U>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "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&
index 4acc9c4987e61a09c9901a7f6e36414c103fff0a..52d64fc1f4f38ef0319d17de5d6c57a71e27b002 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1907,
 /**/
     1906,
 /**/