diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-08-30 16:22:08 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2025-03-27 07:26:42 +0800 |
commit | a9aedfbc5880b9ac25f7b0ac1dc49fa318dbe89b (patch) | |
tree | 95f243b7f7ef18c6a2c62aaa924acf9600e4e62a | |
parent | d5a6040967d8dd32b6cdeceb907ca4d50f56e4c2 (diff) | |
download | rneovim-a9aedfbc5880b9ac25f7b0ac1dc49fa318dbe89b.tar.gz rneovim-a9aedfbc5880b9ac25f7b0ac1dc49fa318dbe89b.tar.bz2 rneovim-a9aedfbc5880b9ac25f7b0ac1dc49fa318dbe89b.zip |
vim-patch:9.1.0605: internal error with fuzzy completion
Problem: internal error with fuzzy completion
(techntools)
Solution: only fuzzy complete the pattern after directory separator
(glepnir)
fixes: vim/vim#15287
closes: vim/vim#15291
https://github.com/vim/vim/commit/0be03e14b9a2899f5e96720e3b21935bd9d2d34e
Co-authored-by: glepnir <glephunter@gmail.com>
-rw-r--r-- | src/nvim/insexpand.c | 25 | ||||
-rw-r--r-- | src/nvim/search.c | 18 | ||||
-rw-r--r-- | test/old/testdir/test_ins_complete.vim | 6 |
3 files changed, 38 insertions, 11 deletions
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 7a123898a5..a02d7a62d2 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -3315,12 +3315,31 @@ static void get_next_filename_completion(void) char **matches; int num_matches; char *leader = ins_compl_leader(); - size_t leader_len = strlen(leader); + size_t leader_len = ins_compl_leader_len(); bool in_fuzzy = ((get_cot_flags() & kOptCotFlagFuzzy) != 0 && leader_len > 0); if (in_fuzzy) { - API_CLEAR_STRING(compl_pattern); - compl_pattern = cbuf_to_string("*", 1); + char *last_sep = strrchr(leader, PATHSEP); + if (last_sep == NULL) { + // No path separator or separator is the last character, + // fuzzy match the whole leader + API_CLEAR_STRING(compl_pattern); + compl_pattern = cbuf_to_string("*", 1); + } else if (*(last_sep + 1) == NUL) { + in_fuzzy = false; + } else { + // Split leader into path and file parts + size_t path_len = (size_t)(last_sep - leader) + 1; + char *path_with_wildcard = xmalloc(path_len + 2); + vim_snprintf(path_with_wildcard, path_len + 2, "%*.*s*", + (int)path_len, (int)path_len, leader); + API_CLEAR_STRING(compl_pattern); + compl_pattern.data = path_with_wildcard; + compl_pattern.size = path_len + 1; + + // Move leader to the file part + leader = last_sep + 1; + } } if (expand_wildcards(1, &compl_pattern.data, &num_matches, &matches, diff --git a/src/nvim/search.c b/src/nvim/search.c index 30653cbe63..756a4c5255 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3689,15 +3689,15 @@ bool search_for_fuzzy_match(buf_T *buf, pos_T *pos, char *pattern, int dir, pos_ current_pos.lnum += dir; } - while (true) { - if (buf == curbuf) { - circly_end = *start_pos; - } else { - circly_end.lnum = buf->b_ml.ml_line_count; - circly_end.col = 0; - circly_end.coladd = 0; - } + if (buf == curbuf) { + circly_end = *start_pos; + } else { + circly_end.lnum = buf->b_ml.ml_line_count; + circly_end.col = 0; + circly_end.coladd = 0; + } + while (true) { // Check if looped around and back to start position if (looped_around && equalpos(current_pos, circly_end)) { break; @@ -3717,6 +3717,8 @@ bool search_for_fuzzy_match(buf_T *buf, pos_T *pos, char *pattern, int dir, pos_ if (found_new_match) { *pos = current_pos; break; + } else if (looped_around && current_pos.lnum == circly_end.lnum) { + break; } } else { if (fuzzy_match_str(*ptr, pattern) > 0) { diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index 9b123a65b6..381a69dd41 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -2871,6 +2871,10 @@ func Test_complete_fuzzy_match() call assert_equal('fobar', getline('.')) call feedkeys("Sfob\<C-X>\<C-f>\<C-N>\<Esc>0", 'tx!') call assert_equal('foobar', getline('.')) + call feedkeys("S../\<C-X>\<C-f>\<Esc>0", 'tx!') + call assert_match('../*', getline('.')) + call feedkeys("S../td\<C-X>\<C-f>\<Esc>0", 'tx!') + call assert_match('../testdir', getline('.')) " can get completion from other buffer set completeopt=fuzzy,menu,menuone @@ -2885,6 +2889,8 @@ func Test_complete_fuzzy_match() call assert_equal('Omnipotent', getline('.')) call feedkeys("Somp\<C-P>\<C-P>\<Esc>0", 'tx!') call assert_equal('Composite', getline('.')) + call feedkeys("S omp\<C-N>\<Esc>0", 'tx!') + call assert_equal(' completeness', getline('.')) " fuzzy on whole line completion call setline(1, ["world is on fire", "no one can save me but you", 'user can execute', '']) |