diff options
author | Yegappan Lakshmanan <yegappan@yahoo.com> | 2022-02-24 13:28:41 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-02-24 13:28:41 +0000 |
commit | 38b85cb4d7216705058708bacbc25ab90cd61595 (patch) | |
tree | 3eb078ed612a835d9d6eecf7e3a4b84f209f1618 /src/search.c | |
parent | 9c9be05b17ececb1515a2f41a4dedbf848d3d8b6 (diff) |
patch 8.2.4463: completion only uses strict matchingv8.2.4463
Problem: Completion only uses strict matching.
Solution: Add the "fuzzy" item for 'wildoptions'. (Yegappan Lakshmanan,
closes #9803)
Diffstat (limited to 'src/search.c')
-rw-r--r-- | src/search.c | 134 |
1 files changed, 131 insertions, 3 deletions
diff --git a/src/search.c b/src/search.c index dbc766f9f5..00a9fdfc6d 100644 --- a/src/search.c +++ b/src/search.c @@ -1166,7 +1166,7 @@ searchit( return submatch + 1; } -#ifdef FEAT_EVAL +#if defined(FEAT_EVAL) || defined(FEAT_PROTO) void set_search_direction(int cdir) { @@ -4107,7 +4107,7 @@ get_spat_last_idx(void) } #endif -#ifdef FEAT_EVAL +#if defined(FEAT_EVAL) || defined(FEAT_PROTO) /* * "searchcount()" function */ @@ -4230,6 +4230,7 @@ the_end: restore_incsearch_state(); #endif } +#endif /* * Fuzzy string matching @@ -4611,6 +4612,7 @@ fuzzy_match( return numMatches != 0; } +#if defined(FEAT_EVAL) || defined(FEAT_PROTO) /* * Sort the fuzzy matches in the descending order of the match score. * For items with same score, retain the order using the index (stable sort) @@ -4933,5 +4935,131 @@ f_matchfuzzypos(typval_T *argvars, typval_T *rettv) { do_fuzzymatch(argvars, rettv, TRUE); } - #endif + +/* + * Same as fuzzy_match_item_compare() except for use with a string match + */ + static int +fuzzy_match_str_compare(const void *s1, const void *s2) +{ + int v1 = ((fuzmatch_str_T *)s1)->score; + int v2 = ((fuzmatch_str_T *)s2)->score; + int idx1 = ((fuzmatch_str_T *)s1)->idx; + int idx2 = ((fuzmatch_str_T *)s2)->idx; + + return v1 == v2 ? (idx1 - idx2) : v1 > v2 ? -1 : 1; +} + +/* + * Sort fuzzy matches by score + */ + static void +fuzzy_match_str_sort(fuzmatch_str_T *fm, int sz) +{ + // Sort the list by the descending order of the match score + qsort((void *)fm, (size_t)sz, sizeof(fuzmatch_str_T), + fuzzy_match_str_compare); +} + +/* + * Same as fuzzy_match_item_compare() except for use with a function name + * string match. <SNR> functions should be sorted to the end. + */ + static int +fuzzy_match_func_compare(const void *s1, const void *s2) +{ + int v1 = ((fuzmatch_str_T *)s1)->score; + int v2 = ((fuzmatch_str_T *)s2)->score; + int idx1 = ((fuzmatch_str_T *)s1)->idx; + int idx2 = ((fuzmatch_str_T *)s2)->idx; + char_u *str1 = ((fuzmatch_str_T *)s1)->str; + char_u *str2 = ((fuzmatch_str_T *)s2)->str; + + if (*str1 != '<' && *str2 == '<') return -1; + if (*str1 == '<' && *str2 != '<') return 1; + return v1 == v2 ? (idx1 - idx2) : v1 > v2 ? -1 : 1; +} + +/* + * Sort fuzzy matches of function names by score. + * <SNR> functions should be sorted to the end. + */ + static void +fuzzy_match_func_sort(fuzmatch_str_T *fm, int sz) +{ + // Sort the list by the descending order of the match score + qsort((void *)fm, (size_t)sz, sizeof(fuzmatch_str_T), + fuzzy_match_func_compare); +} + +/* + * Fuzzy match 'pat' in 'str'. Returns 0 if there is no match. Otherwise, + * returns the match score. + */ + int +fuzzy_match_str(char_u *str, char_u *pat) +{ + int score = 0; + int_u matchpos[256]; + + if (str == NULL || pat == NULL) + return 0; + + fuzzy_match(str, pat, FALSE, &score, matchpos, + sizeof(matchpos) / sizeof(matchpos[0])); + + return score; +} + +/* + * Copy a list of fuzzy matches into a string list after sorting the matches by + * the fuzzy score. Frees the memory allocated for 'fuzmatch'. + * Returns OK on success and FAIL on memory allocation failure. + */ + int +fuzzymatches_to_strmatches( + fuzmatch_str_T *fuzmatch, + char_u ***matches, + int count, + int funcsort) +{ + int i; + + if (count <= 0) + return OK; + + *matches = ALLOC_MULT(char_u *, count); + if (*matches == NULL) + { + for (i = 0; i < count; i++) + vim_free(fuzmatch[i].str); + vim_free(fuzmatch); + return FAIL; + } + + // Sort the list by the descending order of the match score + if (funcsort) + fuzzy_match_func_sort((void *)fuzmatch, (size_t)count); + else + fuzzy_match_str_sort((void *)fuzmatch, (size_t)count); + + for (i = 0; i < count; i++) + (*matches)[i] = fuzmatch[i].str; + vim_free(fuzmatch); + + return OK; +} + +/* + * Free a list of fuzzy string matches. + */ + void +fuzmatch_str_free(fuzmatch_str_T *fuzmatch, int count) +{ + if (count <= 0 || fuzmatch == NULL) + return; + while (count--) + vim_free(fuzmatch[count].str); + vim_free(fuzmatch); +} |