Mercurial > vim
diff src/search.c @ 35737:f70b7cac8073 v9.1.0598
patch 9.1.0598: fuzzy completion does not work with default completion
Commit: https://github.com/vim/vim/commit/8159fb18a92e9a9f5e35201bd92bf651f4d5835c
Author: glepnir <glephunter@gmail.com>
Date: Wed Jul 17 20:32:54 2024 +0200
patch 9.1.0598: fuzzy completion does not work with default completion
Problem: fuzzy completion does not work with default completion
Solution: Make it work (glepnir)
closes: #15193
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Wed, 17 Jul 2024 20:45:03 +0200 |
parents | 5c89a485e597 |
children | c92a560e6f52 |
line wrap: on
line diff
--- a/src/search.c +++ b/src/search.c @@ -53,6 +53,7 @@ static int fuzzy_match_str_compare(const static void fuzzy_match_str_sort(fuzmatch_str_T *fm, int sz); static int fuzzy_match_func_compare(const void *s1, const void *s2); static void fuzzy_match_func_sort(fuzmatch_str_T *fm, int sz); +static int fuzzy_match_str_in_line(char_u **ptr, char_u *pat, int *len, pos_T *current_pos); #define SEARCH_STAT_DEF_TIMEOUT 40L #define SEARCH_STAT_DEF_MAX_COUNT 99 @@ -5140,6 +5141,169 @@ fuzzy_match_str_with_pos(char_u *str UNU } /* + * This function searches for a fuzzy match of the pattern `pat` within the + * line pointed to by `*ptr`. It splits the line into words, performs fuzzy + * matching on each word, and returns the length and position of the first + * matched word. + */ + static int +fuzzy_match_str_in_line(char_u **ptr, char_u *pat, int *len, pos_T *current_pos) +{ + char_u *str = *ptr; + char_u *strBegin = str; + char_u *end = NULL; + char_u *start = NULL; + int found = FALSE; + int result; + char save_end; + + if (str == NULL || pat == NULL) + return found; + + while (*str != NUL) + { + // Skip non-word characters + start = find_word_start(str); + if (*start == NUL) + break; + end = find_word_end(start); + + // Extract the word from start to end + save_end = *end; + *end = NUL; + + // Perform fuzzy match + result = fuzzy_match_str(start, pat); + *end = save_end; + + if (result > 0) + { + *len = (int)(end - start); + current_pos->col += (int)(end - strBegin); + found = TRUE; + *ptr = start; + break; + } + + // Move to the end of the current word for the next iteration + str = end; + // Ensure we continue searching after the current word + while (*str != NUL && !vim_iswordp(str)) + MB_PTR_ADV(str); + } + + return found; +} + +/* + * Search for the next fuzzy match in the specified buffer. + * This function attempts to find the next occurrence of the given pattern + * in the buffer, starting from the current position. It handles line wrapping + * and direction of search. + * + * Return TRUE if a match is found, otherwise FALSE. + */ + int +search_for_fuzzy_match( + buf_T *buf, + pos_T *pos, + char_u *pattern, + int dir, + pos_T *start_pos, + int *len, + char_u **ptr, + int whole_line) +{ + pos_T current_pos = *pos; + pos_T circly_end; + int found_new_match = FAIL; + int looped_around = FALSE; + + if (whole_line) + current_pos.lnum += dir; + + do { + 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; + } + + // Check if looped around and back to start position + if (looped_around && EQUAL_POS(current_pos, circly_end)) + break; + + // Ensure current_pos is valid + if (current_pos.lnum >= 1 && current_pos.lnum <= buf->b_ml.ml_line_count) + { + // Get the current line buffer + *ptr = ml_get_buf(buf, current_pos.lnum, FALSE); + // If ptr is end of line is reached, move to next line + // or previous line based on direction + if (**ptr != NUL) + { + if (!whole_line) + { + *ptr += current_pos.col; + // 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) + { + *pos = current_pos; + break; + } + } + else + { + if (fuzzy_match_str(*ptr, pattern) > 0) + { + found_new_match = TRUE; + *pos = current_pos; + *len = STRLEN(*ptr); + break; + } + } + } + } + + // Move to the next line or previous line based on direction + if (dir == FORWARD) + { + if (++current_pos.lnum > buf->b_ml.ml_line_count) + { + if (p_ws) + { + current_pos.lnum = 1; + looped_around = TRUE; + } + else + break; + } + } + else + { + if (--current_pos.lnum < 1) + { + if (p_ws) + { + current_pos.lnum = buf->b_ml.ml_line_count; + looped_around = TRUE; + } + else + break; + + } + } + current_pos.col = 0; + } while (TRUE); + + return found_new_match; +} + +/* * Free an array of fuzzy string matches "fuzmatch[count]". */ void