mirror of
https://github.com/neovim/neovim.git
synced 2025-10-16 14:56:08 +00:00
vim-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 vim/vim#9803)
38b85cb4d7
Use MAX_FUZZY_MATCHES in fuzzy_match_str().
Omit fuzmatch_str_free() as it is only used on allocation failure.
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
@@ -3111,7 +3111,7 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s
|
||||
/// "outScore" and the matching character positions in "matches".
|
||||
bool fuzzy_match(char *const str, const char *const pat_arg, const bool matchseq,
|
||||
int *const outScore, uint32_t *const matches, const int maxMatches)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
const int len = mb_charlen(str);
|
||||
bool complete = false;
|
||||
@@ -3411,6 +3411,109 @@ void f_matchfuzzypos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
do_fuzzymatch(argvars, rettv, true);
|
||||
}
|
||||
|
||||
/// Same as fuzzy_match_item_compare() except for use with a string match
|
||||
static int fuzzy_match_str_compare(const void *const s1, const void *const s2)
|
||||
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
|
||||
{
|
||||
const int v1 = ((fuzmatch_str_T *)s1)->score;
|
||||
const int v2 = ((fuzmatch_str_T *)s2)->score;
|
||||
const int idx1 = ((fuzmatch_str_T *)s1)->idx;
|
||||
const 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 *const fm, const int sz)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
// Sort the list by the descending order of the match score
|
||||
qsort(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 *const s1, const void *const s2)
|
||||
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
|
||||
{
|
||||
const int v1 = ((fuzmatch_str_T *)s1)->score;
|
||||
const int v2 = ((fuzmatch_str_T *)s2)->score;
|
||||
const int idx1 = ((fuzmatch_str_T *)s1)->idx;
|
||||
const int idx2 = ((fuzmatch_str_T *)s2)->idx;
|
||||
const char *const str1 = ((fuzmatch_str_T *)s1)->str;
|
||||
const char *const 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 *const fm, const int sz)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
// Sort the list by the descending order of the match score
|
||||
qsort(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 *const str, const char *const pat)
|
||||
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (str == NULL || pat == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int score = 0;
|
||||
uint32_t matchpos[MAX_FUZZY_MATCHES];
|
||||
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".
|
||||
void fuzzymatches_to_strmatches(fuzmatch_str_T *const fuzmatch, char ***const matches,
|
||||
const int count, const bool funcsort)
|
||||
FUNC_ATTR_NONNULL_ARG(2)
|
||||
{
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
*matches = xmalloc((size_t)count * sizeof(char *));
|
||||
|
||||
// Sort the list by the descending order of the match score
|
||||
if (funcsort) {
|
||||
fuzzy_match_func_sort(fuzmatch, count);
|
||||
} else {
|
||||
fuzzy_match_str_sort(fuzmatch, count);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
(*matches)[i] = fuzmatch[i].str;
|
||||
}
|
||||
xfree(fuzmatch);
|
||||
}
|
||||
|
||||
/// Free a list of fuzzy string matches.
|
||||
void fuzmatch_str_free(fuzmatch_str_T *const fuzmatch, int count)
|
||||
{
|
||||
if (count <= 0 || fuzmatch == NULL) {
|
||||
return;
|
||||
}
|
||||
while (count--) {
|
||||
xfree(fuzmatch[count].str);
|
||||
}
|
||||
xfree(fuzmatch);
|
||||
}
|
||||
|
||||
/// Get line "lnum" and copy it into "buf[LSIZE]".
|
||||
/// The copy is made because the regexp may make the line invalid when using a
|
||||
/// mark.
|
||||
|
Reference in New Issue
Block a user