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.