aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/insexpand.c4
-rw-r--r--src/nvim/search.c23
-rw-r--r--test/old/testdir/test_ins_complete.vim30
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, &current_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))