mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
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
0be03e14b9
Co-authored-by: glepnir <glephunter@gmail.com>
This commit is contained in:
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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', ''])
|
||||
|
Reference in New Issue
Block a user