comparison src/search.c @ 27875:ae38d2e81fca v8.2.4463

patch 8.2.4463: completion only uses strict matching Commit: https://github.com/vim/vim/commit/38b85cb4d7216705058708bacbc25ab90cd61595 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Thu Feb 24 13:28:41 2022 +0000 patch 8.2.4463: completion only uses strict matching Problem: Completion only uses strict matching. Solution: Add the "fuzzy" item for 'wildoptions'. (Yegappan Lakshmanan, closes #9803)
author Bram Moolenaar <Bram@vim.org>
date Thu, 24 Feb 2022 14:30:05 +0100
parents c1d1639b52dd
children 76e2115dddb8
comparison
equal deleted inserted replaced
27874:f4a227222e7a 27875:ae38d2e81fca
1164 } 1164 }
1165 1165
1166 return submatch + 1; 1166 return submatch + 1;
1167 } 1167 }
1168 1168
1169 #ifdef FEAT_EVAL 1169 #if defined(FEAT_EVAL) || defined(FEAT_PROTO)
1170 void 1170 void
1171 set_search_direction(int cdir) 1171 set_search_direction(int cdir)
1172 { 1172 {
1173 spats[0].off.dir = cdir; 1173 spats[0].off.dir = cdir;
1174 } 1174 }
4105 { 4105 {
4106 return last_idx; 4106 return last_idx;
4107 } 4107 }
4108 #endif 4108 #endif
4109 4109
4110 #ifdef FEAT_EVAL 4110 #if defined(FEAT_EVAL) || defined(FEAT_PROTO)
4111 /* 4111 /*
4112 * "searchcount()" function 4112 * "searchcount()" function
4113 */ 4113 */
4114 void 4114 void
4115 f_searchcount(typval_T *argvars, typval_T *rettv) 4115 f_searchcount(typval_T *argvars, typval_T *rettv)
4228 restore_last_search_pattern(); 4228 restore_last_search_pattern();
4229 #ifdef FEAT_SEARCH_EXTRA 4229 #ifdef FEAT_SEARCH_EXTRA
4230 restore_incsearch_state(); 4230 restore_incsearch_state();
4231 #endif 4231 #endif
4232 } 4232 }
4233 #endif
4233 4234
4234 /* 4235 /*
4235 * Fuzzy string matching 4236 * Fuzzy string matching
4236 * 4237 *
4237 * Ported from the lib_fts library authored by Forrest Smith. 4238 * Ported from the lib_fts library authored by Forrest Smith.
4609 4610
4610 vim_free(save_pat); 4611 vim_free(save_pat);
4611 return numMatches != 0; 4612 return numMatches != 0;
4612 } 4613 }
4613 4614
4615 #if defined(FEAT_EVAL) || defined(FEAT_PROTO)
4614 /* 4616 /*
4615 * Sort the fuzzy matches in the descending order of the match score. 4617 * Sort the fuzzy matches in the descending order of the match score.
4616 * For items with same score, retain the order using the index (stable sort) 4618 * For items with same score, retain the order using the index (stable sort)
4617 */ 4619 */
4618 static int 4620 static int
4931 void 4933 void
4932 f_matchfuzzypos(typval_T *argvars, typval_T *rettv) 4934 f_matchfuzzypos(typval_T *argvars, typval_T *rettv)
4933 { 4935 {
4934 do_fuzzymatch(argvars, rettv, TRUE); 4936 do_fuzzymatch(argvars, rettv, TRUE);
4935 } 4937 }
4936 4938 #endif
4937 #endif 4939
4940 /*
4941 * Same as fuzzy_match_item_compare() except for use with a string match
4942 */
4943 static int
4944 fuzzy_match_str_compare(const void *s1, const void *s2)
4945 {
4946 int v1 = ((fuzmatch_str_T *)s1)->score;
4947 int v2 = ((fuzmatch_str_T *)s2)->score;
4948 int idx1 = ((fuzmatch_str_T *)s1)->idx;
4949 int idx2 = ((fuzmatch_str_T *)s2)->idx;
4950
4951 return v1 == v2 ? (idx1 - idx2) : v1 > v2 ? -1 : 1;
4952 }
4953
4954 /*
4955 * Sort fuzzy matches by score
4956 */
4957 static void
4958 fuzzy_match_str_sort(fuzmatch_str_T *fm, int sz)
4959 {
4960 // Sort the list by the descending order of the match score
4961 qsort((void *)fm, (size_t)sz, sizeof(fuzmatch_str_T),
4962 fuzzy_match_str_compare);
4963 }
4964
4965 /*
4966 * Same as fuzzy_match_item_compare() except for use with a function name
4967 * string match. <SNR> functions should be sorted to the end.
4968 */
4969 static int
4970 fuzzy_match_func_compare(const void *s1, const void *s2)
4971 {
4972 int v1 = ((fuzmatch_str_T *)s1)->score;
4973 int v2 = ((fuzmatch_str_T *)s2)->score;
4974 int idx1 = ((fuzmatch_str_T *)s1)->idx;
4975 int idx2 = ((fuzmatch_str_T *)s2)->idx;
4976 char_u *str1 = ((fuzmatch_str_T *)s1)->str;
4977 char_u *str2 = ((fuzmatch_str_T *)s2)->str;
4978
4979 if (*str1 != '<' && *str2 == '<') return -1;
4980 if (*str1 == '<' && *str2 != '<') return 1;
4981 return v1 == v2 ? (idx1 - idx2) : v1 > v2 ? -1 : 1;
4982 }
4983
4984 /*
4985 * Sort fuzzy matches of function names by score.
4986 * <SNR> functions should be sorted to the end.
4987 */
4988 static void
4989 fuzzy_match_func_sort(fuzmatch_str_T *fm, int sz)
4990 {
4991 // Sort the list by the descending order of the match score
4992 qsort((void *)fm, (size_t)sz, sizeof(fuzmatch_str_T),
4993 fuzzy_match_func_compare);
4994 }
4995
4996 /*
4997 * Fuzzy match 'pat' in 'str'. Returns 0 if there is no match. Otherwise,
4998 * returns the match score.
4999 */
5000 int
5001 fuzzy_match_str(char_u *str, char_u *pat)
5002 {
5003 int score = 0;
5004 int_u matchpos[256];
5005
5006 if (str == NULL || pat == NULL)
5007 return 0;
5008
5009 fuzzy_match(str, pat, FALSE, &score, matchpos,
5010 sizeof(matchpos) / sizeof(matchpos[0]));
5011
5012 return score;
5013 }
5014
5015 /*
5016 * Copy a list of fuzzy matches into a string list after sorting the matches by
5017 * the fuzzy score. Frees the memory allocated for 'fuzmatch'.
5018 * Returns OK on success and FAIL on memory allocation failure.
5019 */
5020 int
5021 fuzzymatches_to_strmatches(
5022 fuzmatch_str_T *fuzmatch,
5023 char_u ***matches,
5024 int count,
5025 int funcsort)
5026 {
5027 int i;
5028
5029 if (count <= 0)
5030 return OK;
5031
5032 *matches = ALLOC_MULT(char_u *, count);
5033 if (*matches == NULL)
5034 {
5035 for (i = 0; i < count; i++)
5036 vim_free(fuzmatch[i].str);
5037 vim_free(fuzmatch);
5038 return FAIL;
5039 }
5040
5041 // Sort the list by the descending order of the match score
5042 if (funcsort)
5043 fuzzy_match_func_sort((void *)fuzmatch, (size_t)count);
5044 else
5045 fuzzy_match_str_sort((void *)fuzmatch, (size_t)count);
5046
5047 for (i = 0; i < count; i++)
5048 (*matches)[i] = fuzmatch[i].str;
5049 vim_free(fuzmatch);
5050
5051 return OK;
5052 }
5053
5054 /*
5055 * Free a list of fuzzy string matches.
5056 */
5057 void
5058 fuzmatch_str_free(fuzmatch_str_T *fuzmatch, int count)
5059 {
5060 if (count <= 0 || fuzmatch == NULL)
5061 return;
5062 while (count--)
5063 vim_free(fuzmatch[count].str);
5064 vim_free(fuzmatch);
5065 }