diff options
-rw-r--r-- | src/nvim/insexpand.c | 4 | ||||
-rw-r--r-- | src/nvim/search.c | 23 | ||||
-rw-r--r-- | test/old/testdir/test_ins_complete.vim | 30 |
3 files changed, 56 insertions, 1 deletions
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index f2ad4c0757..226cfeb322 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -4822,6 +4822,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()) { @@ -4836,6 +4837,9 @@ static int ins_compl_start(void) compl_length = 0; compl_col = curwin->w_cursor.col; compl_lnum = curwin->w_cursor.lnum; + } 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 756a4c5255..19de55666f 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3684,6 +3684,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; @@ -3715,6 +3717,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 3accb1f286..97a02adf0d 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -2900,10 +2900,38 @@ func Test_complete_fuzzy_match() call feedkeys("Su\<C-X>\<C-L>\<C-P>\<Esc>0", 'tx!') call assert_equal('no one can save me but you', getline('.')) + " issue #15412 + call setline(1, ['alpha bravio charlie']) + call feedkeys("Salpha\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('alpha bravio', getline('.')) + call feedkeys("Salp\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('alpha', getline('.')) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('alpha bravio', getline('.')) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('alpha bravio charlie', getline('.')) + + set complete-=i + call feedkeys("Salp\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('alpha', getline('.')) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('alpha bravio', getline('.')) + call feedkeys("A\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('alpha bravio charlie', getline('.')) + + call setline(1, ['alpha bravio charlie', 'alpha another']) + call feedkeys("Salpha\<C-X>\<C-N>\<C-N>\<Esc>0", 'tx!') + call assert_equal('alpha another', getline('.')) + call setline(1, ['你好 我好', '你好 他好']) + call feedkeys("S你好\<C-X>\<C-N>\<Esc>0", 'tx!') + call assert_equal('你好 我好', getline('.')) + call feedkeys("S你好\<C-X>\<C-N>\<C-N>\<Esc>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\<C-X>\<C-N>x\<CR>\<Esc>0", 'tx!') call assert_equal('Tex', getline(line('.') - 1)) |