From 28fa71d74312f9e2282aef4f6bf21930bd423c85 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 16 Sep 2024 09:10:51 +0800 Subject: [PATCH] vim-patch:9.1.0733: keyword completion does not work with fuzzy Problem: keyword completion does not work with fuzzy (egesip) Solution: handle ctrl_x_mode_normal() specifically (glepnir) fixes: vim/vim#15412 closes: vim/vim#15424 https://github.com/vim/vim/commit/7cfe693f9bfa74690867e4d96c25f2205d0d13e4 Co-authored-by: glepnir --- src/nvim/insexpand.c | 4 ++++ src/nvim/search.c | 23 ++++++++++++++++++++ test/old/testdir/test_ins_complete.vim | 30 +++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index b375d11385..7333150722 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -4602,6 +4602,7 @@ static int ins_compl_start(void) line = ml_get(curwin->w_cursor.lnum); } + bool in_fuzzy = get_cot_flags() & kOptCotFlagFuzzy; if (compl_status_adding()) { edit_submode_pre = _(" Adding"); if (ctrl_x_mode_line_or_eval()) { @@ -4615,6 +4616,9 @@ static int ins_compl_start(void) curbuf->b_p_com = old; compl_length = 0; compl_col = curwin->w_cursor.col; + } else if (ctrl_x_mode_normal() && in_fuzzy) { + compl_startpos = curwin->w_cursor; + compl_cont_status &= CONT_S_IPOS; } } else { edit_submode_pre = NULL; diff --git a/src/nvim/search.c b/src/nvim/search.c index 827047d8c7..f5df4bddc0 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3628,6 +3628,8 @@ bool search_for_fuzzy_match(buf_T *buf, pos_T *pos, char *pattern, int dir, pos_ pos_T circly_end; bool found_new_match = false; bool looped_around = false; + char *next_word_end = NULL; + char *match_word = NULL; if (whole_line) { current_pos.lnum += dir; @@ -3659,6 +3661,27 @@ bool search_for_fuzzy_match(buf_T *buf, pos_T *pos, char *pattern, int dir, pos_ // Try to find a fuzzy match in the current line starting from current position found_new_match = fuzzy_match_str_in_line(ptr, pattern, len, ¤t_pos); if (found_new_match) { + if (ctrl_x_mode_normal()) { + match_word = xstrnsave(*ptr, (size_t)(*len)); + if (strcmp(match_word, pattern) == 0) { + next_word_end = find_word_start(*ptr + *len); + if (*next_word_end != NUL && *next_word_end != NL) { + // Find end of the word. + while (*next_word_end != NUL) { + int l = utfc_ptr2len(next_word_end); + if (l < 2 && !vim_iswordc(*next_word_end)) { + break; + } + next_word_end += l; + } + } else if (looped_around) { + found_new_match = false; + } + *len = (int)(next_word_end - *ptr); + current_pos.col = *len; + } + xfree(match_word); + } *pos = current_pos; break; } else if (looped_around && current_pos.lnum == circly_end.lnum) { diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index d139135012..815e18b97a 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -2898,10 +2898,38 @@ func Test_complete_fuzzy_match() call feedkeys("Su\\\\0", 'tx!') call assert_equal('no one can save me but you', getline('.')) + " issue #15412 + call setline(1, ['alpha bravio charlie']) + call feedkeys("Salpha\\\0", 'tx!') + call assert_equal('alpha bravio', getline('.')) + call feedkeys("Salp\\\0", 'tx!') + call assert_equal('alpha', getline('.')) + call feedkeys("A\\\0", 'tx!') + call assert_equal('alpha bravio', getline('.')) + call feedkeys("A\\\0", 'tx!') + call assert_equal('alpha bravio charlie', getline('.')) + + set complete-=i + call feedkeys("Salp\\\0", 'tx!') + call assert_equal('alpha', getline('.')) + call feedkeys("A\\\0", 'tx!') + call assert_equal('alpha bravio', getline('.')) + call feedkeys("A\\\0", 'tx!') + call assert_equal('alpha bravio charlie', getline('.')) + + call setline(1, ['alpha bravio charlie', 'alpha another']) + call feedkeys("Salpha\\\\0", 'tx!') + call assert_equal('alpha another', getline('.')) + call setline(1, ['你好 我好', '你好 他好']) + call feedkeys("S你好\\\0", 'tx!') + call assert_equal('你好 我好', getline('.')) + call feedkeys("S你好\\\\0", 'tx!') + call assert_equal('你好 他好', getline('.')) + " issue #15526 set completeopt=fuzzy,menuone,menu,noselect call setline(1, ['Text', 'ToText', '']) - call cursor(2, 1) + call cursor(3, 1) call feedkeys("STe\\x\\0", 'tx!') call assert_equal('Tex', getline('.'))