patch 9.1.0484: Sorting of completeopt+=fuzzy is not stable

Commit: 
https://github.com/vim/vim/commit/8e56747fd26b3b040b6fcbfb6be41b7d5922c6b5
Author: zeertzjq <zeert...@outlook.com>
Date:   Fri Jun 14 20:04:42 2024 +0200

    patch 9.1.0484: Sorting of completeopt+=fuzzy is not stable
    
    Problem:  Sorting of completeopt+=fuzzy is not stable.
    Solution: Compare original indexes when scores are the same.
              (zeertzjq)
    
    closes: #14988
    
    Signed-off-by: zeertzjq <zeert...@outlook.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/insexpand.c b/src/insexpand.c
index 74be94cf4..fafa7a2f0 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -1203,11 +1203,13 @@ trigger_complete_changed_event(int cur)
  * pumitem qsort compare func
  */
     static int
-ins_compl_fuzzy_sort(const void *a, const void *b)
+ins_compl_fuzzy_cmp(const void *a, const void *b)
 {
     const int sa = (*(pumitem_T *)a).pum_score;
     const int sb = (*(pumitem_T *)b).pum_score;
-    return sa == sb ? 0 : sa < sb ? 1 : -1;
+    const int ia = (*(pumitem_T *)a).pum_idx;
+    const int ib = (*(pumitem_T *)b).pum_idx;
+    return sa == sb ? (ia == ib ? 0 : (ia < ib ? -1 : 1)) : (sa < sb ? 1 : -1);
 }
 
 /*
@@ -1355,8 +1357,13 @@ ins_compl_build_pum(void)
     } while (compl != NULL && !is_first_match(compl));
 
     if (compl_fuzzy_match && compl_leader != NULL && lead_len > 0)
+    {
+       for (i = 0; i < compl_match_arraysize; i++)
+           compl_match_array[i].pum_idx = i;
        // sort by the largest score of fuzzy match
-       qsort(compl_match_array, (size_t)compl_match_arraysize, 
sizeof(pumitem_T), ins_compl_fuzzy_sort);
+       qsort(compl_match_array, (size_t)compl_match_arraysize,
+                                      sizeof(pumitem_T), ins_compl_fuzzy_cmp);
+    }
 
     if (!shown_match_ok)    // no displayed match at all
        cur = -1;
diff --git a/src/structs.h b/src/structs.h
index f1bbf1735..7e21f0fc8 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -4470,7 +4470,8 @@ typedef struct
     char_u     *pum_kind;      // extra kind text (may be truncated)
     char_u     *pum_extra;     // extra menu text (may be truncated)
     char_u     *pum_info;      // extra info
-    int                 pum_score;     // fuzzy match score
+    int                pum_score;      // fuzzy match score
+    int                pum_idx;        // index of item before sorting by score
 } pumitem_T;
 
 /*
diff --git a/src/testdir/test_ins_complete.vim 
b/src/testdir/test_ins_complete.vim
index ad9f4978e..c2cc484c8 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -2578,4 +2578,24 @@ func Test_complete_fuzzy_match()
   unlet g:word
 endfunc
 
+" Check that tie breaking is stable for completeopt+=fuzzy (which should
+" behave the same on different platforms).
+func Test_complete_fuzzy_match_tie()
+  new
+  set completeopt+=fuzzy,noselect
+  call setline(1, ['aaabbccc', 'aaabbCCC', 'aaabbcccc', 'aaabbCCCC', ''])
+
+  call feedkeys("Gcc\<C-X>\<C-N>ab\<C-N>\<C-Y>", 'tx')
+  call assert_equal('aaabbccc', getline('.'))
+  call feedkeys("Gcc\<C-X>\<C-N>ab\<C-N>\<C-N>\<C-Y>", 'tx')
+  call assert_equal('aaabbCCC', getline('.'))
+  call feedkeys("Gcc\<C-X>\<C-N>ab\<C-N>\<C-N>\<C-N>\<C-Y>", 'tx')
+  call assert_equal('aaabbcccc', getline('.'))
+  call feedkeys("Gcc\<C-X>\<C-N>ab\<C-N>\<C-N>\<C-N>\<C-N>\<C-Y>", 'tx')
+  call assert_equal('aaabbCCCC', getline('.'))
+
+  bwipe!
+  set completeopt&
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab nofoldenable
diff --git a/src/version.c b/src/version.c
index 2df207108..36761aaed 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 */
+/**/
+    484,
 /**/
     483,
 /**/

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1sIBS7-00Cuxw-J0%40256bit.org.

Raspunde prin e-mail lui