patch 9.0.2018: complete_info() returns wrong index

Commit: 
https://github.com/vim/vim/commit/69fb5afb3bc9da24c2fb0eafb0027ba9c6502fc2
Author: LemonBoy <[email protected]>
Date:   Wed Oct 11 21:55:56 2023 +0200

    patch 9.0.2018: complete_info() returns wrong index
    
    Problem:  complete_info() returns wrong index
    Solution: Make order of 'info' in completion_info consistent
    
    Start the iteration from the same point and follow the same direction as
    done when assigning the completion numbers. This way we remove the
    dependence on the completion direction and make the order of 'info'
    consistent.
    
    closes: #12230
    closes: #12971
    
    Signed-off-by: Christian Brabandt <[email protected]>
    Co-authored-by: LemonBoy <[email protected]>

diff --git a/src/insexpand.c b/src/insexpand.c
index 3b06ee02d..f225cd384 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -3040,6 +3040,43 @@ ins_compl_update_sequence_numbers(void)
     }
 }
 
+    static int
+info_add_completion_info(list_T *li)
+{
+    compl_T    *match;
+
+    if (compl_first_match == NULL)
+       return OK;
+
+    // Skip the element with the CP_ORIGINAL_TEXT flag at the beginning, in 
case of
+    // forward completion, or at the end, in case of backward completion.
+    match = compl_dir_forward()
+           ? compl_first_match->cp_next : compl_first_match->cp_prev->cp_prev;
+    while (match != NULL && !match_at_original_text(match))
+    {
+       dict_T *di = dict_alloc();
+
+       if (di == NULL)
+           return FAIL;
+       if (list_append_dict(li, di) == FAIL)
+           return FAIL;
+       dict_add_string(di, "word", match->cp_str);
+       dict_add_string(di, "abbr", match->cp_text[CPT_ABBR]);
+       dict_add_string(di, "menu", match->cp_text[CPT_MENU]);
+       dict_add_string(di, "kind", match->cp_text[CPT_KIND]);
+       dict_add_string(di, "info", match->cp_text[CPT_INFO]);
+       if (match->cp_user_data.v_type == VAR_UNKNOWN)
+           // Add an empty string for backwards compatibility
+           dict_add_string(di, "user_data", (char_u *)"");
+       else
+           dict_add_tv(di, "user_data", &match->cp_user_data);
+
+       match = compl_dir_forward() ? match->cp_next : match->cp_prev;
+    }
+
+    return OK;
+}
+
 /*
  * Get complete information
  */
@@ -3088,41 +3125,13 @@ get_complete_info(list_T *what_list, dict_T *retdict)
     if (ret == OK && (what_flag & CI_WHAT_ITEMS))
     {
        list_T      *li;
-       dict_T      *di;
-       compl_T     *match;
 
        li = list_alloc();
        if (li == NULL)
            return;
        ret = dict_add_list(retdict, "items", li);
-       if (ret == OK && compl_first_match != NULL)
-       {
-           match = compl_first_match;
-           do
-           {
-               if (!match_at_original_text(match))
-               {
-                   di = dict_alloc();
-                   if (di == NULL)
-                       return;
-                   ret = list_append_dict(li, di);
-                   if (ret != OK)
-                       return;
-                   dict_add_string(di, "word", match->cp_str);
-                   dict_add_string(di, "abbr", match->cp_text[CPT_ABBR]);
-                   dict_add_string(di, "menu", match->cp_text[CPT_MENU]);
-                   dict_add_string(di, "kind", match->cp_text[CPT_KIND]);
-                   dict_add_string(di, "info", match->cp_text[CPT_INFO]);
-                   if (match->cp_user_data.v_type == VAR_UNKNOWN)
-                       // Add an empty string for backwards compatibility
-                       dict_add_string(di, "user_data", (char_u *)"");
-                   else
-                       dict_add_tv(di, "user_data", &match->cp_user_data);
-               }
-               match = match->cp_next;
-           }
-           while (match != NULL && !is_first_match(match));
-       }
+       if (ret == OK)
+           ret = info_add_completion_info(li);
     }
 
     if (ret == OK && (what_flag & CI_WHAT_SELECTED))
diff --git a/src/testdir/test_ins_complete.vim 
b/src/testdir/test_ins_complete.vim
index cedc09f7a..c7f9e9b28 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -2243,5 +2243,43 @@ func Test_ins_complete_popup_position()
   call StopVimInTerminal(buf)
 endfunc
 
+func GetCompleteInfo()
+  let g:compl_info = complete_info()
+  return ''
+endfunc
+
+func Test_complete_info_index()
+  new
+  call setline(1, ["aaa", "bbb", "ccc", "ddd", "eee", "fff"])
+  inoremap <buffer><F5> <C-R>=GetCompleteInfo()<CR>
+
+  " Ensure 'index' in complete_info() is coherent with the 'items' array.
+
+  set completeopt=menu,preview
+  " Search forward.
+  call feedkeys("Go\<C-X>\<C-N>\<F5>\<Esc>_dd", 'tx')
+  call assert_equal("aaa", 
g:compl_info['items'][g:compl_info['selected']]['word'])
+  call feedkeys("Go\<C-X>\<C-N>\<C-N>\<F5>\<Esc>_dd", 'tx')
+  call assert_equal("bbb", 
g:compl_info['items'][g:compl_info['selected']]['word'])
+
+  " Search backward.
+  call feedkeys("Go\<C-X>\<C-P>\<F5>\<Esc>_dd", 'tx')
+  call assert_equal("fff", 
g:compl_info['items'][g:compl_info['selected']]['word'])
+  call feedkeys("Go\<C-X>\<C-P>\<C-P>\<F5>\<Esc>_dd", 'tx')
+  call assert_equal("eee", 
g:compl_info['items'][g:compl_info['selected']]['word'])
+
+  " Add 'noselect', check that 'selected' is -1 when nothing is selected.
+  set completeopt+=noselect
+  " Search forward.
+  call feedkeys("Go\<C-X>\<C-N>\<F5>\<Esc>_dd", 'tx')
+  call assert_equal(-1, g:compl_info['selected'])
+
+  " Search backward.
+  call feedkeys("Go\<C-X>\<C-P>\<F5>\<Esc>_dd", 'tx')
+  call assert_equal(-1, g:compl_info['selected'])
+
+  set completeopt&
+  bwipe!
+endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 7db93c42b..d05016389 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 */
+/**/
+    2018,
 /**/
     2017,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1qqfbk-001CUI-Qq%40256bit.org.

Raspunde prin e-mail lui