vim-patch:9.1.1185: endless loop with completefuzzycollect and no match found

Problem:  endless loop with completefuzzycollect and no match found
Solution: move pointer to line end and break loop

closes: vim/vim#16820

dd42b05f8a

Co-authored-by: glepnir <glephunter@gmail.com>
This commit is contained in:
zeertzjq
2025-03-09 06:23:25 +08:00
parent 10fde593f1
commit cd95ea5d48
3 changed files with 13 additions and 6 deletions

View File

@@ -1735,8 +1735,6 @@ static void ins_compl_files(int count, char **files, bool thesaurus, int flags,
&& score == compl_first_match->cp_next->cp_score) { && score == compl_first_match->cp_next->cp_score) {
compl_num_bests++; compl_num_bests++;
} }
} else if (find_word_end(ptr) == line_end) {
break;
} }
} }
} }
@@ -1778,7 +1776,7 @@ char *find_word_end(char *ptr)
/// Find the end of the line, omitting CR and NL at the end. /// Find the end of the line, omitting CR and NL at the end.
/// ///
/// @return a pointer to just after the line. /// @return a pointer to just after the line.
static char *find_line_end(char *ptr) char *find_line_end(char *ptr)
{ {
char *s = ptr + strlen(ptr); char *s = ptr + strlen(ptr);
while (s > ptr && (s[-1] == CAR || s[-1] == NL)) { while (s > ptr && (s[-1] == CAR || s[-1] == NL)) {

View File

@@ -3629,8 +3629,7 @@ garray_T *fuzzy_match_str_with_pos(char *const str, const char *const pat)
/// - `*len` is set to the length of the matched word. /// - `*len` is set to the length of the matched word.
/// - `*score` contains the match score. /// - `*score` contains the match score.
/// ///
/// If no match is found, `*ptr` is updated to point beyond the last word /// If no match is found, `*ptr` is updated to to the end of the line.
/// or to the end of the line.
bool fuzzy_match_str_in_line(char **ptr, char *pat, int *len, pos_T *current_pos, int *score) bool fuzzy_match_str_in_line(char **ptr, char *pat, int *len, pos_T *current_pos, int *score)
{ {
char *str = *ptr; char *str = *ptr;
@@ -3642,8 +3641,9 @@ bool fuzzy_match_str_in_line(char **ptr, char *pat, int *len, pos_T *current_pos
if (str == NULL || pat == NULL) { if (str == NULL || pat == NULL) {
return found; return found;
} }
char *line_end = find_line_end(str);
while (*str != NUL) { while (str < line_end) {
// Skip non-word characters // Skip non-word characters
start = find_word_start(str); start = find_word_start(str);
if (*start == NUL) { if (*start == NUL) {
@@ -3677,6 +3677,10 @@ bool fuzzy_match_str_in_line(char **ptr, char *pat, int *len, pos_T *current_pos
} }
} }
if (!found) {
*ptr = line_end;
}
return found; return found;
} }

View File

@@ -3038,6 +3038,11 @@ func Test_cfc_with_longest()
call writefile([' auto int enum register', 'why'], 'test_case4.txt', 'D') call writefile([' auto int enum register', 'why'], 'test_case4.txt', 'D')
exe "normal ggdGSe\<C-N>\<C-N>\<ESC>" exe "normal ggdGSe\<C-N>\<C-N>\<ESC>"
call assert_equal("enum", getline('.')) call assert_equal("enum", getline('.'))
set complete=ktest_case5.txt
call writefile(['hello friends', 'go', 'hero'], 'test_case5.txt', 'D')
exe "normal ggdGSh\<C-N>\<C-N>\<ESC>"
call assert_equal("hero", getline('.'))
set complete& set complete&
" file " file