mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
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)
This commit is contained in:
committed by
Bram Moolenaar
parent
9c9be05b17
commit
38b85cb4d7
@@ -9087,6 +9087,14 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
feature}
|
feature}
|
||||||
A list of words that change how |cmdline-completion| is done.
|
A list of words that change how |cmdline-completion| is done.
|
||||||
The following values are supported:
|
The following values are supported:
|
||||||
|
fuzzy Use fuzzy matching to find completion matches. When
|
||||||
|
this value is specified, wildcard expansion will not
|
||||||
|
be used for completion. The matches will be sorted by
|
||||||
|
the "best match" rather than alphabetically sorted.
|
||||||
|
This will find more matches than the wildcard
|
||||||
|
expansion. Currently fuzzy matching based completion
|
||||||
|
is not supported for file and directory names and
|
||||||
|
instead wildcard expansion is used.
|
||||||
pum Display the completion matches using the popupmenu
|
pum Display the completion matches using the popupmenu
|
||||||
in the same style as the |ins-completion-menu|.
|
in the same style as the |ins-completion-menu|.
|
||||||
tagfile When using CTRL-D to list matching tags, the kind of
|
tagfile When using CTRL-D to list matching tags, the kind of
|
||||||
|
171
src/buffer.c
171
src/buffer.c
@@ -2728,10 +2728,12 @@ ExpandBufnames(
|
|||||||
int round;
|
int round;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
int attempt;
|
int attempt;
|
||||||
char_u *patc;
|
char_u *patc = NULL;
|
||||||
#ifdef FEAT_VIMINFO
|
#ifdef FEAT_VIMINFO
|
||||||
bufmatch_T *matches = NULL;
|
bufmatch_T *matches = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
int fuzzy;
|
||||||
|
fuzmatch_str_T *fuzmatch = NULL;
|
||||||
|
|
||||||
*num_file = 0; // return values in case of FAIL
|
*num_file = 0; // return values in case of FAIL
|
||||||
*file = NULL;
|
*file = NULL;
|
||||||
@@ -2741,32 +2743,42 @@ ExpandBufnames(
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Make a copy of "pat" and change "^" to "\(^\|[\/]\)".
|
fuzzy = cmdline_fuzzy_complete(pat);
|
||||||
if (*pat == '^')
|
|
||||||
|
// Make a copy of "pat" and change "^" to "\(^\|[\/]\)" (if doing regular
|
||||||
|
// expression matching)
|
||||||
|
if (!fuzzy)
|
||||||
{
|
{
|
||||||
patc = alloc(STRLEN(pat) + 11);
|
if (*pat == '^')
|
||||||
if (patc == NULL)
|
{
|
||||||
return FAIL;
|
patc = alloc(STRLEN(pat) + 11);
|
||||||
STRCPY(patc, "\\(^\\|[\\/]\\)");
|
if (patc == NULL)
|
||||||
STRCPY(patc + 11, pat + 1);
|
return FAIL;
|
||||||
|
STRCPY(patc, "\\(^\\|[\\/]\\)");
|
||||||
|
STRCPY(patc + 11, pat + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
patc = pat;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
patc = pat;
|
|
||||||
|
|
||||||
// attempt == 0: try match with '\<', match at start of word
|
// attempt == 0: try match with '\<', match at start of word
|
||||||
// attempt == 1: try match without '\<', match anywhere
|
// attempt == 1: try match without '\<', match anywhere
|
||||||
for (attempt = 0; attempt <= 1; ++attempt)
|
for (attempt = 0; attempt <= (fuzzy ? 0 : 1); ++attempt)
|
||||||
{
|
{
|
||||||
regmatch_T regmatch;
|
regmatch_T regmatch;
|
||||||
|
int score = 0;
|
||||||
|
|
||||||
if (attempt > 0 && patc == pat)
|
if (!fuzzy)
|
||||||
break; // there was no anchor, no need to try again
|
|
||||||
regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
|
|
||||||
if (regmatch.regprog == NULL)
|
|
||||||
{
|
{
|
||||||
if (patc != pat)
|
if (attempt > 0 && patc == pat)
|
||||||
vim_free(patc);
|
break; // there was no anchor, no need to try again
|
||||||
return FAIL;
|
regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
|
||||||
|
if (regmatch.regprog == NULL)
|
||||||
|
{
|
||||||
|
if (patc != pat)
|
||||||
|
vim_free(patc);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// round == 1: Count the matches.
|
// round == 1: Count the matches.
|
||||||
@@ -2786,7 +2798,22 @@ ExpandBufnames(
|
|||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p = buflist_match(®match, buf, p_wic);
|
if (!fuzzy)
|
||||||
|
p = buflist_match(®match, buf, p_wic);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = NULL;
|
||||||
|
// first try matching with the short file name
|
||||||
|
if ((score = fuzzy_match_str(buf->b_sfname, pat)) != 0)
|
||||||
|
p = buf->b_sfname;
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
// next try matching with the full path file name
|
||||||
|
if ((score = fuzzy_match_str(buf->b_ffname, pat)) != 0)
|
||||||
|
p = buf->b_ffname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (p != NULL)
|
if (p != NULL)
|
||||||
{
|
{
|
||||||
if (round == 1)
|
if (round == 1)
|
||||||
@@ -2797,16 +2824,27 @@ ExpandBufnames(
|
|||||||
p = home_replace_save(buf, p);
|
p = home_replace_save(buf, p);
|
||||||
else
|
else
|
||||||
p = vim_strsave(p);
|
p = vim_strsave(p);
|
||||||
#ifdef FEAT_VIMINFO
|
|
||||||
if (matches != NULL)
|
if (!fuzzy)
|
||||||
{
|
{
|
||||||
matches[count].buf = buf;
|
#ifdef FEAT_VIMINFO
|
||||||
matches[count].match = p;
|
if (matches != NULL)
|
||||||
count++;
|
{
|
||||||
|
matches[count].buf = buf;
|
||||||
|
matches[count].match = p;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
(*file)[count++] = p;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
{
|
||||||
(*file)[count++] = p;
|
fuzmatch[count].idx = count;
|
||||||
|
fuzmatch[count].str = p;
|
||||||
|
fuzmatch[count].score = score;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2814,47 +2852,72 @@ ExpandBufnames(
|
|||||||
break;
|
break;
|
||||||
if (round == 1)
|
if (round == 1)
|
||||||
{
|
{
|
||||||
*file = ALLOC_MULT(char_u *, count);
|
if (!fuzzy)
|
||||||
if (*file == NULL)
|
|
||||||
{
|
{
|
||||||
vim_regfree(regmatch.regprog);
|
*file = ALLOC_MULT(char_u *, count);
|
||||||
if (patc != pat)
|
if (*file == NULL)
|
||||||
vim_free(patc);
|
{
|
||||||
return FAIL;
|
vim_regfree(regmatch.regprog);
|
||||||
}
|
if (patc != pat)
|
||||||
|
vim_free(patc);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
#ifdef FEAT_VIMINFO
|
#ifdef FEAT_VIMINFO
|
||||||
if (options & WILD_BUFLASTUSED)
|
if (options & WILD_BUFLASTUSED)
|
||||||
matches = ALLOC_MULT(bufmatch_T, count);
|
matches = ALLOC_MULT(bufmatch_T, count);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fuzmatch = ALLOC_MULT(fuzmatch_str_T, count);
|
||||||
|
if (fuzmatch == NULL)
|
||||||
|
{
|
||||||
|
*num_file = 0;
|
||||||
|
*file = NULL;
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vim_regfree(regmatch.regprog);
|
|
||||||
if (count) // match(es) found, break here
|
if (!fuzzy)
|
||||||
break;
|
{
|
||||||
|
vim_regfree(regmatch.regprog);
|
||||||
|
if (count) // match(es) found, break here
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patc != pat)
|
if (!fuzzy && patc != pat)
|
||||||
vim_free(patc);
|
vim_free(patc);
|
||||||
|
|
||||||
#ifdef FEAT_VIMINFO
|
#ifdef FEAT_VIMINFO
|
||||||
if (matches != NULL)
|
if (!fuzzy)
|
||||||
{
|
{
|
||||||
int i;
|
if (matches != NULL)
|
||||||
if (count > 1)
|
|
||||||
qsort(matches, count, sizeof(bufmatch_T), buf_compare);
|
|
||||||
// if the current buffer is first in the list, place it at the end
|
|
||||||
if (matches[0].buf == curbuf)
|
|
||||||
{
|
{
|
||||||
for (i = 1; i < count; i++)
|
int i;
|
||||||
(*file)[i-1] = matches[i].match;
|
if (count > 1)
|
||||||
(*file)[count-1] = matches[0].match;
|
qsort(matches, count, sizeof(bufmatch_T), buf_compare);
|
||||||
|
// if the current buffer is first in the list, place it at the end
|
||||||
|
if (matches[0].buf == curbuf)
|
||||||
|
{
|
||||||
|
for (i = 1; i < count; i++)
|
||||||
|
(*file)[i-1] = matches[i].match;
|
||||||
|
(*file)[count-1] = matches[0].match;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
(*file)[i] = matches[i].match;
|
||||||
|
}
|
||||||
|
vim_free(matches);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
for (i = 0; i < count; i++)
|
{
|
||||||
(*file)[i] = matches[i].match;
|
if (fuzzymatches_to_strmatches(fuzmatch, file, count, FALSE) == FAIL)
|
||||||
}
|
return FAIL;
|
||||||
vim_free(matches);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
121
src/cmdexpand.c
121
src/cmdexpand.c
@@ -18,7 +18,8 @@ static int cmd_showtail; // Only show path tail in lists ?
|
|||||||
static void set_expand_context(expand_T *xp);
|
static void set_expand_context(expand_T *xp);
|
||||||
static int ExpandGeneric(expand_T *xp, regmatch_T *regmatch,
|
static int ExpandGeneric(expand_T *xp, regmatch_T *regmatch,
|
||||||
char_u ***matches, int *numMatches,
|
char_u ***matches, int *numMatches,
|
||||||
char_u *((*func)(expand_T *, int)), int escaped);
|
char_u *((*func)(expand_T *, int)), int escaped,
|
||||||
|
char_u *fuzzystr);
|
||||||
static int ExpandFromContext(expand_T *xp, char_u *, char_u ***, int *, int);
|
static int ExpandFromContext(expand_T *xp, char_u *, char_u ***, int *, int);
|
||||||
static int expand_showtail(expand_T *xp);
|
static int expand_showtail(expand_T *xp);
|
||||||
static int expand_shellcmd(char_u *filepat, char_u ***matches, int *numMatches, int flagsarg);
|
static int expand_shellcmd(char_u *filepat, char_u ***matches, int *numMatches, int flagsarg);
|
||||||
@@ -39,6 +40,43 @@ static int compl_selected;
|
|||||||
|
|
||||||
#define SHOW_FILE_TEXT(m) (showtail ? sm_gettail(matches[m]) : matches[m])
|
#define SHOW_FILE_TEXT(m) (showtail ? sm_gettail(matches[m]) : matches[m])
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns TRUE if fuzzy completion is supported for a given cmdline completion
|
||||||
|
* context.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cmdline_fuzzy_completion_supported(expand_T *xp)
|
||||||
|
{
|
||||||
|
return (vim_strchr(p_wop, WOP_FUZZY) != NULL
|
||||||
|
&& xp->xp_context != EXPAND_BOOL_SETTINGS
|
||||||
|
&& xp->xp_context != EXPAND_COLORS
|
||||||
|
&& xp->xp_context != EXPAND_COMPILER
|
||||||
|
&& xp->xp_context != EXPAND_DIRECTORIES
|
||||||
|
&& xp->xp_context != EXPAND_FILES
|
||||||
|
&& xp->xp_context != EXPAND_FILES_IN_PATH
|
||||||
|
&& xp->xp_context != EXPAND_FILETYPE
|
||||||
|
&& xp->xp_context != EXPAND_HELP
|
||||||
|
&& xp->xp_context != EXPAND_MAPPINGS
|
||||||
|
&& xp->xp_context != EXPAND_OLD_SETTING
|
||||||
|
&& xp->xp_context != EXPAND_OWNSYNTAX
|
||||||
|
&& xp->xp_context != EXPAND_PACKADD
|
||||||
|
&& xp->xp_context != EXPAND_SHELLCMD
|
||||||
|
&& xp->xp_context != EXPAND_TAGS
|
||||||
|
&& xp->xp_context != EXPAND_TAGS_LISTFILES
|
||||||
|
&& xp->xp_context != EXPAND_USER_DEFINED
|
||||||
|
&& xp->xp_context != EXPAND_USER_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns TRUE if fuzzy completion for cmdline completion is enabled and
|
||||||
|
* 'fuzzystr' is not empty.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cmdline_fuzzy_complete(char_u *fuzzystr)
|
||||||
|
{
|
||||||
|
return vim_strchr(p_wop, WOP_FUZZY) != NULL && *fuzzystr != NUL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sort function for the completion matches.
|
* sort function for the completion matches.
|
||||||
* <SNR> functions should be sorted to the end.
|
* <SNR> functions should be sorted to the end.
|
||||||
@@ -195,9 +233,14 @@ nextwild(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (cmdline_fuzzy_completion_supported(xp))
|
||||||
|
// If fuzzy matching, don't modify the search string
|
||||||
|
p1 = vim_strsave(xp->xp_pattern);
|
||||||
|
else
|
||||||
|
p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
|
||||||
|
|
||||||
// Translate string into pattern and expand it.
|
// Translate string into pattern and expand it.
|
||||||
if ((p1 = addstar(xp->xp_pattern, xp->xp_pattern_len,
|
if (p1 == NULL)
|
||||||
xp->xp_context)) == NULL)
|
|
||||||
p2 = NULL;
|
p2 = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2188,9 +2231,15 @@ expand_cmdline(
|
|||||||
|
|
||||||
// add star to file name, or convert to regexp if not exp. files.
|
// add star to file name, or convert to regexp if not exp. files.
|
||||||
xp->xp_pattern_len = (int)(str + col - xp->xp_pattern);
|
xp->xp_pattern_len = (int)(str + col - xp->xp_pattern);
|
||||||
file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
|
if (cmdline_fuzzy_completion_supported(xp))
|
||||||
if (file_str == NULL)
|
// If fuzzy matching, don't modify the search string
|
||||||
return EXPAND_UNSUCCESSFUL;
|
file_str = vim_strsave(xp->xp_pattern);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
|
||||||
|
if (file_str == NULL)
|
||||||
|
return EXPAND_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
if (p_wic)
|
if (p_wic)
|
||||||
options += WILD_ICASE;
|
options += WILD_ICASE;
|
||||||
@@ -2317,6 +2366,7 @@ get_mapclear_arg(expand_T *xp UNUSED, int idx)
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ExpandOther(
|
ExpandOther(
|
||||||
|
char_u *pat,
|
||||||
expand_T *xp,
|
expand_T *xp,
|
||||||
regmatch_T *rmp,
|
regmatch_T *rmp,
|
||||||
char_u ***matches,
|
char_u ***matches,
|
||||||
@@ -2386,10 +2436,16 @@ ExpandOther(
|
|||||||
{
|
{
|
||||||
if (xp->xp_context == tab[i].context)
|
if (xp->xp_context == tab[i].context)
|
||||||
{
|
{
|
||||||
|
// Use fuzzy matching if 'wildoptions' has 'fuzzy'.
|
||||||
|
// If no search pattern is supplied, then don't use fuzzy
|
||||||
|
// matching and return all the found items.
|
||||||
|
int fuzzy = cmdline_fuzzy_complete(pat);
|
||||||
|
|
||||||
if (tab[i].ic)
|
if (tab[i].ic)
|
||||||
rmp->rm_ic = TRUE;
|
rmp->rm_ic = TRUE;
|
||||||
ret = ExpandGeneric(xp, rmp, matches, numMatches,
|
ret = ExpandGeneric(xp, rmp, matches, numMatches,
|
||||||
tab[i].func, tab[i].escaped);
|
tab[i].func, tab[i].escaped,
|
||||||
|
fuzzy ? pat : NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2530,7 +2586,7 @@ ExpandFromContext(
|
|||||||
|
|
||||||
if (xp->xp_context == EXPAND_SETTINGS
|
if (xp->xp_context == EXPAND_SETTINGS
|
||||||
|| xp->xp_context == EXPAND_BOOL_SETTINGS)
|
|| xp->xp_context == EXPAND_BOOL_SETTINGS)
|
||||||
ret = ExpandSettings(xp, ®match, numMatches, matches);
|
ret = ExpandSettings(xp, ®match, pat, numMatches, matches);
|
||||||
else if (xp->xp_context == EXPAND_MAPPINGS)
|
else if (xp->xp_context == EXPAND_MAPPINGS)
|
||||||
ret = ExpandMappings(®match, numMatches, matches);
|
ret = ExpandMappings(®match, numMatches, matches);
|
||||||
# if defined(FEAT_EVAL)
|
# if defined(FEAT_EVAL)
|
||||||
@@ -2538,7 +2594,7 @@ ExpandFromContext(
|
|||||||
ret = ExpandUserDefined(xp, ®match, matches, numMatches);
|
ret = ExpandUserDefined(xp, ®match, matches, numMatches);
|
||||||
# endif
|
# endif
|
||||||
else
|
else
|
||||||
ret = ExpandOther(xp, ®match, matches, numMatches);
|
ret = ExpandOther(pat, xp, ®match, matches, numMatches);
|
||||||
|
|
||||||
vim_regfree(regmatch.regprog);
|
vim_regfree(regmatch.regprog);
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
@@ -2553,6 +2609,9 @@ ExpandFromContext(
|
|||||||
* obtain strings, one by one. The strings are matched against a regexp
|
* obtain strings, one by one. The strings are matched against a regexp
|
||||||
* program. Matching strings are copied into an array, which is returned.
|
* program. Matching strings are copied into an array, which is returned.
|
||||||
*
|
*
|
||||||
|
* If 'fuzzy' is TRUE, then fuzzy matching is used. Otherwise, regex matching
|
||||||
|
* is used.
|
||||||
|
*
|
||||||
* Returns OK when no problems encountered, FAIL for error (out of memory).
|
* Returns OK when no problems encountered, FAIL for error (out of memory).
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
@@ -2563,12 +2622,17 @@ ExpandGeneric(
|
|||||||
int *numMatches,
|
int *numMatches,
|
||||||
char_u *((*func)(expand_T *, int)),
|
char_u *((*func)(expand_T *, int)),
|
||||||
// returns a string from the list
|
// returns a string from the list
|
||||||
int escaped)
|
int escaped,
|
||||||
|
char_u *fuzzystr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int round;
|
int round;
|
||||||
char_u *str;
|
char_u *str;
|
||||||
|
fuzmatch_str_T *fuzmatch = NULL;
|
||||||
|
int score = 0;
|
||||||
|
int fuzzy = (fuzzystr != NULL);
|
||||||
|
int funcsort = FALSE;
|
||||||
|
|
||||||
// do this loop twice:
|
// do this loop twice:
|
||||||
// round == 0: count the number of matching names
|
// round == 0: count the number of matching names
|
||||||
@@ -2583,7 +2647,8 @@ ExpandGeneric(
|
|||||||
if (*str == NUL) // skip empty strings
|
if (*str == NUL) // skip empty strings
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (vim_regexec(regmatch, str, (colnr_T)0))
|
if (vim_regexec(regmatch, str, (colnr_T)0) ||
|
||||||
|
(fuzzy && ((score = fuzzy_match_str(str, fuzzystr)) != 0)))
|
||||||
{
|
{
|
||||||
if (round)
|
if (round)
|
||||||
{
|
{
|
||||||
@@ -2594,11 +2659,20 @@ ExpandGeneric(
|
|||||||
if (str == NULL)
|
if (str == NULL)
|
||||||
{
|
{
|
||||||
FreeWild(count, *matches);
|
FreeWild(count, *matches);
|
||||||
|
if (fuzzy)
|
||||||
|
fuzmatch_str_free(fuzmatch, count);
|
||||||
*numMatches = 0;
|
*numMatches = 0;
|
||||||
*matches = NULL;
|
*matches = NULL;
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
(*matches)[count] = str;
|
if (fuzzy)
|
||||||
|
{
|
||||||
|
fuzmatch[count].idx = count;
|
||||||
|
fuzmatch[count].str = str;
|
||||||
|
fuzmatch[count].score = score;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(*matches)[count] = str;
|
||||||
# ifdef FEAT_MENU
|
# ifdef FEAT_MENU
|
||||||
if (func == get_menu_names && str != NULL)
|
if (func == get_menu_names && str != NULL)
|
||||||
{
|
{
|
||||||
@@ -2616,8 +2690,11 @@ ExpandGeneric(
|
|||||||
{
|
{
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return OK;
|
return OK;
|
||||||
*matches = ALLOC_MULT(char_u *, count);
|
if (fuzzy)
|
||||||
if (*matches == NULL)
|
fuzmatch = ALLOC_MULT(fuzmatch_str_T, count);
|
||||||
|
else
|
||||||
|
*matches = ALLOC_MULT(char_u *, count);
|
||||||
|
if ((fuzzy && (fuzmatch == NULL)) || (*matches == NULL))
|
||||||
{
|
{
|
||||||
*numMatches = 0;
|
*numMatches = 0;
|
||||||
*matches = NULL;
|
*matches = NULL;
|
||||||
@@ -2635,11 +2712,18 @@ ExpandGeneric(
|
|||||||
|| xp->xp_context == EXPAND_FUNCTIONS
|
|| xp->xp_context == EXPAND_FUNCTIONS
|
||||||
|| xp->xp_context == EXPAND_USER_FUNC
|
|| xp->xp_context == EXPAND_USER_FUNC
|
||||||
|| xp->xp_context == EXPAND_DISASSEMBLE)
|
|| xp->xp_context == EXPAND_DISASSEMBLE)
|
||||||
|
{
|
||||||
// <SNR> functions should be sorted to the end.
|
// <SNR> functions should be sorted to the end.
|
||||||
qsort((void *)*matches, (size_t)*numMatches, sizeof(char_u *),
|
funcsort = TRUE;
|
||||||
|
if (!fuzzy)
|
||||||
|
qsort((void *)*matches, (size_t)*numMatches, sizeof(char_u *),
|
||||||
sort_func_compare);
|
sort_func_compare);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
sort_strings(*matches, *numMatches);
|
{
|
||||||
|
if (!fuzzy)
|
||||||
|
sort_strings(*matches, *numMatches);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FEAT_SYN_HL)
|
#if defined(FEAT_SYN_HL)
|
||||||
@@ -2647,6 +2731,11 @@ ExpandGeneric(
|
|||||||
// they don't show up when getting normal highlight names by ID.
|
// they don't show up when getting normal highlight names by ID.
|
||||||
reset_expand_highlight();
|
reset_expand_highlight();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (fuzzy && fuzzymatches_to_strmatches(fuzmatch, matches, count,
|
||||||
|
funcsort) == FAIL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
200
src/option.c
200
src/option.c
@@ -6447,12 +6447,70 @@ set_context_in_set_cmd(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns TRUE if 'str' either matches 'regmatch' or fuzzy matches 'pat'.
|
||||||
|
*
|
||||||
|
* If 'test_only' is TRUE and 'fuzzy' is FALSE and if 'str' matches the regular
|
||||||
|
* expression 'regmatch', then returns TRUE. Otherwise returns FALSE.
|
||||||
|
*
|
||||||
|
* If 'test_only' is FALSE and 'fuzzy' is FALSE and if 'str' matches the
|
||||||
|
* regular expression 'regmatch', then stores the match in matches[idx] and
|
||||||
|
* returns TRUE.
|
||||||
|
*
|
||||||
|
* If 'test_only' is TRUE and 'fuzzy' is TRUE and if 'str' fuzzy matches
|
||||||
|
* 'fuzzystr', then returns TRUE. Otherwise returns FALSE.
|
||||||
|
*
|
||||||
|
* If 'test_only' is FALSE and 'fuzzy' is TRUE and if 'str' fuzzy matches
|
||||||
|
* 'fuzzystr', then stores the match details in fuzmatch[idx] and returns TRUE.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
match_str(
|
||||||
|
char_u *str,
|
||||||
|
regmatch_T *regmatch,
|
||||||
|
char_u **matches,
|
||||||
|
int idx,
|
||||||
|
int test_only,
|
||||||
|
int fuzzy,
|
||||||
|
char_u *fuzzystr,
|
||||||
|
fuzmatch_str_T *fuzmatch)
|
||||||
|
{
|
||||||
|
if (!fuzzy)
|
||||||
|
{
|
||||||
|
if (vim_regexec(regmatch, str, (colnr_T)0))
|
||||||
|
{
|
||||||
|
if (!test_only)
|
||||||
|
matches[idx] = vim_strsave(str);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int score;
|
||||||
|
|
||||||
|
score = fuzzy_match_str(str, fuzzystr);
|
||||||
|
if (score != 0)
|
||||||
|
{
|
||||||
|
if (!test_only)
|
||||||
|
{
|
||||||
|
fuzmatch[idx].idx = idx;
|
||||||
|
fuzmatch[idx].str = vim_strsave(str);
|
||||||
|
fuzmatch[idx].score = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ExpandSettings(
|
ExpandSettings(
|
||||||
expand_T *xp,
|
expand_T *xp,
|
||||||
regmatch_T *regmatch,
|
regmatch_T *regmatch,
|
||||||
int *num_file,
|
char_u *fuzzystr,
|
||||||
char_u ***file)
|
int *numMatches,
|
||||||
|
char_u ***matches)
|
||||||
{
|
{
|
||||||
int num_normal = 0; // Nr of matching non-term-code settings
|
int num_normal = 0; // Nr of matching non-term-code settings
|
||||||
int num_term = 0; // Nr of matching terminal code settings
|
int num_term = 0; // Nr of matching terminal code settings
|
||||||
@@ -6465,6 +6523,10 @@ ExpandSettings(
|
|||||||
char_u name_buf[MAX_KEY_NAME_LEN];
|
char_u name_buf[MAX_KEY_NAME_LEN];
|
||||||
static char *(names[]) = {"all", "termcap"};
|
static char *(names[]) = {"all", "termcap"};
|
||||||
int ic = regmatch->rm_ic; // remember the ignore-case flag
|
int ic = regmatch->rm_ic; // remember the ignore-case flag
|
||||||
|
int fuzzy;
|
||||||
|
fuzmatch_str_T *fuzmatch = NULL;
|
||||||
|
|
||||||
|
fuzzy = cmdline_fuzzy_complete(fuzzystr);
|
||||||
|
|
||||||
// do this loop twice:
|
// do this loop twice:
|
||||||
// loop == 0: count the number of matching options
|
// loop == 0: count the number of matching options
|
||||||
@@ -6475,13 +6537,16 @@ ExpandSettings(
|
|||||||
if (xp->xp_context != EXPAND_BOOL_SETTINGS)
|
if (xp->xp_context != EXPAND_BOOL_SETTINGS)
|
||||||
{
|
{
|
||||||
for (match = 0; match < (int)ARRAY_LENGTH(names); ++match)
|
for (match = 0; match < (int)ARRAY_LENGTH(names); ++match)
|
||||||
if (vim_regexec(regmatch, (char_u *)names[match], (colnr_T)0))
|
{
|
||||||
|
if (match_str((char_u *)names[match], regmatch, *matches,
|
||||||
|
count, (loop == 0), fuzzy, fuzzystr, fuzmatch))
|
||||||
{
|
{
|
||||||
if (loop == 0)
|
if (loop == 0)
|
||||||
num_normal++;
|
num_normal++;
|
||||||
else
|
else
|
||||||
(*file)[count++] = vim_strsave((char_u *)names[match]);
|
count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
|
for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
|
||||||
opt_idx++)
|
opt_idx++)
|
||||||
@@ -6494,28 +6559,9 @@ ExpandSettings(
|
|||||||
is_term_opt = istermoption_idx(opt_idx);
|
is_term_opt = istermoption_idx(opt_idx);
|
||||||
if (is_term_opt && num_normal > 0)
|
if (is_term_opt && num_normal > 0)
|
||||||
continue;
|
continue;
|
||||||
match = FALSE;
|
|
||||||
if (vim_regexec(regmatch, str, (colnr_T)0)
|
if (match_str(str, regmatch, *matches, count, (loop == 0),
|
||||||
|| (options[opt_idx].shortname != NULL
|
fuzzy, fuzzystr, fuzmatch))
|
||||||
&& vim_regexec(regmatch,
|
|
||||||
(char_u *)options[opt_idx].shortname, (colnr_T)0)))
|
|
||||||
match = TRUE;
|
|
||||||
else if (is_term_opt)
|
|
||||||
{
|
|
||||||
name_buf[0] = '<';
|
|
||||||
name_buf[1] = 't';
|
|
||||||
name_buf[2] = '_';
|
|
||||||
name_buf[3] = str[2];
|
|
||||||
name_buf[4] = str[3];
|
|
||||||
name_buf[5] = '>';
|
|
||||||
name_buf[6] = NUL;
|
|
||||||
if (vim_regexec(regmatch, name_buf, (colnr_T)0))
|
|
||||||
{
|
|
||||||
match = TRUE;
|
|
||||||
str = name_buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (match)
|
|
||||||
{
|
{
|
||||||
if (loop == 0)
|
if (loop == 0)
|
||||||
{
|
{
|
||||||
@@ -6525,9 +6571,46 @@ ExpandSettings(
|
|||||||
num_normal++;
|
num_normal++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
(*file)[count++] = vim_strsave(str);
|
count++;
|
||||||
|
}
|
||||||
|
else if (!fuzzy && options[opt_idx].shortname != NULL
|
||||||
|
&& vim_regexec(regmatch,
|
||||||
|
(char_u *)options[opt_idx].shortname, (colnr_T)0))
|
||||||
|
{
|
||||||
|
// Compare against the abbreviated option name (for regular
|
||||||
|
// expression match). Fuzzy matching (previous if) already
|
||||||
|
// matches against both the expanded and abbreviated names.
|
||||||
|
if (loop == 0)
|
||||||
|
{
|
||||||
|
if (is_term_opt)
|
||||||
|
num_term++;
|
||||||
|
else
|
||||||
|
num_normal++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(*matches)[count++] = vim_strsave(str);
|
||||||
|
}
|
||||||
|
else if (is_term_opt)
|
||||||
|
{
|
||||||
|
name_buf[0] = '<';
|
||||||
|
name_buf[1] = 't';
|
||||||
|
name_buf[2] = '_';
|
||||||
|
name_buf[3] = str[2];
|
||||||
|
name_buf[4] = str[3];
|
||||||
|
name_buf[5] = '>';
|
||||||
|
name_buf[6] = NUL;
|
||||||
|
|
||||||
|
if (match_str(name_buf, regmatch, *matches, count, (loop == 0),
|
||||||
|
fuzzy, fuzzystr, fuzmatch))
|
||||||
|
{
|
||||||
|
if (loop == 0)
|
||||||
|
num_term++;
|
||||||
|
else
|
||||||
|
count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check terminal key codes, these are not in the option table
|
* Check terminal key codes, these are not in the option table
|
||||||
*/
|
*/
|
||||||
@@ -6544,9 +6627,14 @@ ExpandSettings(
|
|||||||
name_buf[3] = str[1];
|
name_buf[3] = str[1];
|
||||||
name_buf[4] = NUL;
|
name_buf[4] = NUL;
|
||||||
|
|
||||||
match = FALSE;
|
if (match_str(name_buf, regmatch, *matches, count,
|
||||||
if (vim_regexec(regmatch, name_buf, (colnr_T)0))
|
(loop == 0), fuzzy, fuzzystr, fuzmatch))
|
||||||
match = TRUE;
|
{
|
||||||
|
if (loop == 0)
|
||||||
|
num_term++;
|
||||||
|
else
|
||||||
|
count++;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
name_buf[0] = '<';
|
name_buf[0] = '<';
|
||||||
@@ -6557,15 +6645,15 @@ ExpandSettings(
|
|||||||
name_buf[5] = '>';
|
name_buf[5] = '>';
|
||||||
name_buf[6] = NUL;
|
name_buf[6] = NUL;
|
||||||
|
|
||||||
if (vim_regexec(regmatch, name_buf, (colnr_T)0))
|
if (match_str(name_buf, regmatch, *matches, count,
|
||||||
match = TRUE;
|
(loop == 0), fuzzy, fuzzystr,
|
||||||
}
|
fuzmatch))
|
||||||
if (match)
|
{
|
||||||
{
|
if (loop == 0)
|
||||||
if (loop == 0)
|
num_term++;
|
||||||
num_term++;
|
else
|
||||||
else
|
count++;
|
||||||
(*file)[count++] = vim_strsave(name_buf);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6579,31 +6667,49 @@ ExpandSettings(
|
|||||||
STRCPY(name_buf + 1, str);
|
STRCPY(name_buf + 1, str);
|
||||||
STRCAT(name_buf, ">");
|
STRCAT(name_buf, ">");
|
||||||
|
|
||||||
if (vim_regexec(regmatch, name_buf, (colnr_T)0))
|
if (match_str(name_buf, regmatch, *matches, count, (loop == 0),
|
||||||
|
fuzzy, fuzzystr, fuzmatch))
|
||||||
{
|
{
|
||||||
if (loop == 0)
|
if (loop == 0)
|
||||||
num_term++;
|
num_term++;
|
||||||
else
|
else
|
||||||
(*file)[count++] = vim_strsave(name_buf);
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (loop == 0)
|
if (loop == 0)
|
||||||
{
|
{
|
||||||
if (num_normal > 0)
|
if (num_normal > 0)
|
||||||
*num_file = num_normal;
|
*numMatches = num_normal;
|
||||||
else if (num_term > 0)
|
else if (num_term > 0)
|
||||||
*num_file = num_term;
|
*numMatches = num_term;
|
||||||
else
|
else
|
||||||
return OK;
|
return OK;
|
||||||
*file = ALLOC_MULT(char_u *, *num_file);
|
if (!fuzzy)
|
||||||
if (*file == NULL)
|
|
||||||
{
|
{
|
||||||
*file = (char_u **)"";
|
*matches = ALLOC_MULT(char_u *, *numMatches);
|
||||||
return FAIL;
|
if (*matches == NULL)
|
||||||
|
{
|
||||||
|
*matches = (char_u **)"";
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fuzmatch = ALLOC_MULT(fuzmatch_str_T, *numMatches);
|
||||||
|
if (fuzmatch == NULL)
|
||||||
|
{
|
||||||
|
*matches = (char_u **)"";
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fuzzy &&
|
||||||
|
fuzzymatches_to_strmatches(fuzmatch, matches, count, FALSE) == FAIL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -358,6 +358,7 @@ typedef enum {
|
|||||||
|
|
||||||
// flags for the 'wildoptions' option
|
// flags for the 'wildoptions' option
|
||||||
// each defined char should be unique over all values.
|
// each defined char should be unique over all values.
|
||||||
|
#define WOP_FUZZY 'z'
|
||||||
#define WOP_TAGFILE 't'
|
#define WOP_TAGFILE 't'
|
||||||
#define WOP_PUM 'p'
|
#define WOP_PUM 'p'
|
||||||
|
|
||||||
|
@@ -57,7 +57,7 @@ static char *(p_tbis_values[]) = {"tiny", "small", "medium", "large", "huge", "g
|
|||||||
static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", "urxvt", "sgr", NULL};
|
static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", "urxvt", "sgr", NULL};
|
||||||
#endif
|
#endif
|
||||||
static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", "none", "NONE", NULL};
|
static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", "none", "NONE", NULL};
|
||||||
static char *(p_wop_values[]) = {"tagfile", "pum", NULL};
|
static char *(p_wop_values[]) = {"fuzzy", "tagfile", "pum", NULL};
|
||||||
#ifdef FEAT_WAK
|
#ifdef FEAT_WAK
|
||||||
static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
|
static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
/* cmdexpand.c */
|
/* cmdexpand.c */
|
||||||
|
int cmdline_fuzzy_complete(char_u *fuzzystr);
|
||||||
int nextwild(expand_T *xp, int type, int options, int escape);
|
int nextwild(expand_T *xp, int type, int options, int escape);
|
||||||
char_u *ExpandOne(expand_T *xp, char_u *str, char_u *orig, int options, int mode);
|
char_u *ExpandOne(expand_T *xp, char_u *str, char_u *orig, int options, int mode);
|
||||||
void ExpandInit(expand_T *xp);
|
void ExpandInit(expand_T *xp);
|
||||||
|
@@ -63,7 +63,7 @@ void reset_modifiable(void);
|
|||||||
void set_iminsert_global(void);
|
void set_iminsert_global(void);
|
||||||
void set_imsearch_global(void);
|
void set_imsearch_global(void);
|
||||||
void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags);
|
void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags);
|
||||||
int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file);
|
int ExpandSettings(expand_T *xp, regmatch_T *regmatch, char_u *pat, int *numMatches, char_u ***matches);
|
||||||
int ExpandOldSetting(int *num_file, char_u ***file);
|
int ExpandOldSetting(int *num_file, char_u ***file);
|
||||||
int shortmess(int x);
|
int shortmess(int x);
|
||||||
void vimrc_found(char_u *fname, char_u *envname);
|
void vimrc_found(char_u *fname, char_u *envname);
|
||||||
|
@@ -40,4 +40,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv);
|
|||||||
int fuzzy_match(char_u *str, char_u *pat_arg, int matchseq, int *outScore, int_u *matches, int maxMatches);
|
int fuzzy_match(char_u *str, char_u *pat_arg, int matchseq, int *outScore, int_u *matches, int maxMatches);
|
||||||
void f_matchfuzzy(typval_T *argvars, typval_T *rettv);
|
void f_matchfuzzy(typval_T *argvars, typval_T *rettv);
|
||||||
void f_matchfuzzypos(typval_T *argvars, typval_T *rettv);
|
void f_matchfuzzypos(typval_T *argvars, typval_T *rettv);
|
||||||
|
int fuzzy_match_str(char_u *str, char_u *pat);
|
||||||
|
int fuzzymatches_to_strmatches(fuzmatch_str_T *fuzmatch, char_u ***matches, int count, int funcsort);
|
||||||
|
void fuzmatch_str_free(fuzmatch_str_T *fuzmatch, int count);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
134
src/search.c
134
src/search.c
@@ -1166,7 +1166,7 @@ searchit(
|
|||||||
return submatch + 1;
|
return submatch + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_EVAL
|
#if defined(FEAT_EVAL) || defined(FEAT_PROTO)
|
||||||
void
|
void
|
||||||
set_search_direction(int cdir)
|
set_search_direction(int cdir)
|
||||||
{
|
{
|
||||||
@@ -4107,7 +4107,7 @@ get_spat_last_idx(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FEAT_EVAL
|
#if defined(FEAT_EVAL) || defined(FEAT_PROTO)
|
||||||
/*
|
/*
|
||||||
* "searchcount()" function
|
* "searchcount()" function
|
||||||
*/
|
*/
|
||||||
@@ -4230,6 +4230,7 @@ the_end:
|
|||||||
restore_incsearch_state();
|
restore_incsearch_state();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fuzzy string matching
|
* Fuzzy string matching
|
||||||
@@ -4611,6 +4612,7 @@ fuzzy_match(
|
|||||||
return numMatches != 0;
|
return numMatches != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(FEAT_EVAL) || defined(FEAT_PROTO)
|
||||||
/*
|
/*
|
||||||
* Sort the fuzzy matches in the descending order of the match score.
|
* 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)
|
* 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);
|
do_fuzzymatch(argvars, rettv, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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);
|
||||||
|
}
|
||||||
|
@@ -4516,3 +4516,11 @@ typedef struct {
|
|||||||
int sw_same_win; // VIsual_active was not reset
|
int sw_same_win; // VIsual_active was not reset
|
||||||
int sw_visual_active;
|
int sw_visual_active;
|
||||||
} switchwin_T;
|
} switchwin_T;
|
||||||
|
|
||||||
|
// Fuzzy matched string list item. Used for fuzzy match completion. Items are
|
||||||
|
// usually sorted by 'score'. The 'idx' member is used for stable-sort.
|
||||||
|
typedef struct {
|
||||||
|
int idx;
|
||||||
|
char_u *str;
|
||||||
|
int score;
|
||||||
|
} fuzmatch_str_T;
|
||||||
|
@@ -11,6 +11,7 @@ set nomore
|
|||||||
" Clear out t_WS, we don't want to resize the actual terminal.
|
" Clear out t_WS, we don't want to resize the actual terminal.
|
||||||
let script = [
|
let script = [
|
||||||
\ '" DO NOT EDIT: Generated with gen_opt_test.vim',
|
\ '" DO NOT EDIT: Generated with gen_opt_test.vim',
|
||||||
|
\ '" Used by test_options.vim.',
|
||||||
\ '',
|
\ '',
|
||||||
\ 'let save_columns = &columns',
|
\ 'let save_columns = &columns',
|
||||||
\ 'let save_lines = &lines',
|
\ 'let save_lines = &lines',
|
||||||
@@ -152,7 +153,7 @@ let test_values = {
|
|||||||
\ 'virtualedit': [['', 'all', 'all,block'], ['xxx']],
|
\ 'virtualedit': [['', 'all', 'all,block'], ['xxx']],
|
||||||
\ 'whichwrap': [['', 'b,s', 'bs'], ['xxx']],
|
\ 'whichwrap': [['', 'b,s', 'bs'], ['xxx']],
|
||||||
\ 'wildmode': [['', 'full', 'list:full', 'full,longest'], ['xxx', 'a4', 'full,full,full,full,full']],
|
\ 'wildmode': [['', 'full', 'list:full', 'full,longest'], ['xxx', 'a4', 'full,full,full,full,full']],
|
||||||
\ 'wildoptions': [['', 'tagfile'], ['xxx']],
|
\ 'wildoptions': [['', 'tagfile', 'pum', 'fuzzy'], ['xxx']],
|
||||||
\ 'winaltkeys': [['menu', 'no'], ['', 'xxx']],
|
\ 'winaltkeys': [['menu', 'no'], ['', 'xxx']],
|
||||||
\
|
\
|
||||||
\ 'luadll': [[], []],
|
\ 'luadll': [[], []],
|
||||||
|
@@ -1574,6 +1574,12 @@ func Test_cmdwin_jump_to_win()
|
|||||||
call assert_equal(1, winnr('$'))
|
call assert_equal(1, winnr('$'))
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_cmdwin_tabpage()
|
||||||
|
tabedit
|
||||||
|
call assert_fails("silent norm q/g :I\<Esc>", 'E11:')
|
||||||
|
tabclose!
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_cmdwin_interrupted()
|
func Test_cmdwin_interrupted()
|
||||||
CheckFeature cmdwin
|
CheckFeature cmdwin
|
||||||
CheckScreendump
|
CheckScreendump
|
||||||
@@ -2438,4 +2444,321 @@ func Test_cmdline_complete_dlist()
|
|||||||
call assert_equal("\"dlist 10 /pat/ | chistory", @:)
|
call assert_equal("\"dlist 10 /pat/ | chistory", @:)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test for 'fuzzy' in 'wildoptions' (fuzzy completion)
|
||||||
|
func Test_wildoptions_fuzzy()
|
||||||
|
" argument list (only for :argdel)
|
||||||
|
argadd change.py count.py charge.py
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":argdel cge\<C-A>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"argdel cge', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":argdel cge\<C-A>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"argdel change.py charge.py', @:)
|
||||||
|
%argdelete
|
||||||
|
|
||||||
|
" autocmd group name fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
augroup MyFuzzyGroup
|
||||||
|
augroup END
|
||||||
|
call feedkeys(":augroup mfg\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"augroup mfg', @:)
|
||||||
|
call feedkeys(":augroup My*p\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"augroup MyFuzzyGroup', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":augroup mfg\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"augroup MyFuzzyGroup', @:)
|
||||||
|
call feedkeys(":augroup My*p\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"augroup My*p', @:)
|
||||||
|
augroup! MyFuzzyGroup
|
||||||
|
|
||||||
|
" buffer name fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
edit SomeFile.txt
|
||||||
|
enew
|
||||||
|
call feedkeys(":b SF\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"b SF', @:)
|
||||||
|
call feedkeys(":b S*File.txt\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"b SomeFile.txt', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":b SF\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"b SomeFile.txt', @:)
|
||||||
|
call feedkeys(":b S*File.txt\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"b S*File.txt', @:)
|
||||||
|
%bw!
|
||||||
|
|
||||||
|
" buffer name (full path) fuzzy completion
|
||||||
|
if has('unix')
|
||||||
|
set wildoptions&
|
||||||
|
call mkdir('Xcmd/Xstate/Xfile.js', 'p')
|
||||||
|
edit Xcmd/Xstate/Xfile.js
|
||||||
|
cd Xcmd/Xstate
|
||||||
|
enew
|
||||||
|
call feedkeys(":b CmdStateFile\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"b CmdStateFile', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":b CmdStateFile\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_match('Xcmd/Xstate/Xfile.js$', @:)
|
||||||
|
cd -
|
||||||
|
call delete('Xcmd', 'rf')
|
||||||
|
endif
|
||||||
|
|
||||||
|
" :behave suboptions fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":behave xm\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"behave xm', @:)
|
||||||
|
call feedkeys(":behave xt*m\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"behave xterm', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":behave xm\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"behave xterm', @:)
|
||||||
|
call feedkeys(":behave xt*m\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"behave xt*m', @:)
|
||||||
|
let g:Sline = ''
|
||||||
|
call feedkeys(":behave win\<C-D>\<F4>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('mswin', g:Sline)
|
||||||
|
call assert_equal('"behave win', @:)
|
||||||
|
|
||||||
|
" colorscheme name fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" built-in command name fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":sbwin\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"sbwin', @:)
|
||||||
|
call feedkeys(":sbr*d\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"sbrewind', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":sbwin\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"sbrewind', @:)
|
||||||
|
call feedkeys(":sbr*d\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"sbr*d', @:)
|
||||||
|
|
||||||
|
" compiler name fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" :cscope suboptions fuzzy completion
|
||||||
|
if has('cscope')
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":cscope ret\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"cscope ret', @:)
|
||||||
|
call feedkeys(":cscope re*t\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"cscope reset', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":cscope ret\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"cscope reset', @:)
|
||||||
|
call feedkeys(":cscope re*t\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"cscope re*t', @:)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" :diffget/:diffput buffer name fuzzy completion
|
||||||
|
new SomeBuffer
|
||||||
|
diffthis
|
||||||
|
new OtherBuffer
|
||||||
|
diffthis
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":diffget sbuf\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"diffget sbuf', @:)
|
||||||
|
call feedkeys(":diffput sbuf\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"diffput sbuf', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":diffget sbuf\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"diffget SomeBuffer', @:)
|
||||||
|
call feedkeys(":diffput sbuf\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"diffput SomeBuffer', @:)
|
||||||
|
%bw!
|
||||||
|
|
||||||
|
" directory name fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" environment variable name fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":echo $VUT\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"echo $VUT', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":echo $VUT\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"echo $VIMRUNTIME', @:)
|
||||||
|
|
||||||
|
" autocmd event fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":autocmd BWout\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"autocmd BWout', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":autocmd BWout\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"autocmd BufWipeout', @:)
|
||||||
|
|
||||||
|
" vim expression fuzzy completion
|
||||||
|
let g:PerPlaceCount = 10
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":let c = ppc\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"let c = ppc', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":let c = ppc\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"let c = PerPlaceCount', @:)
|
||||||
|
|
||||||
|
" file name fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" files in path fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" filetype name fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" user defined function name completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":call Test_w_fuz\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"call Test_w_fuz', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":call Test_w_fuz\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"call Test_wildoptions_fuzzy()', @:)
|
||||||
|
|
||||||
|
" user defined command name completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":MsFeat\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"MsFeat', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":MsFeat\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"MissingFeature', @:)
|
||||||
|
|
||||||
|
" :help tag fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" highlight group name fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":highlight SKey\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"highlight SKey', @:)
|
||||||
|
call feedkeys(":highlight Sp*Key\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"highlight SpecialKey', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":highlight SKey\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"highlight SpecialKey', @:)
|
||||||
|
call feedkeys(":highlight Sp*Key\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"highlight Sp*Key', @:)
|
||||||
|
|
||||||
|
" :history suboptions fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":history dg\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"history dg', @:)
|
||||||
|
call feedkeys(":history se*h\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"history search', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":history dg\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"history debug', @:)
|
||||||
|
call feedkeys(":history se*h\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"history se*h', @:)
|
||||||
|
|
||||||
|
" :language locale name fuzzy completion
|
||||||
|
if has('unix')
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":lang psx\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"lang psx', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":lang psx\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"lang POSIX', @:)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" :mapclear buffer argument fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":mapclear buf\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"mapclear buf', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":mapclear buf\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"mapclear <buffer>', @:)
|
||||||
|
|
||||||
|
" map name fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" menu name fuzzy completion
|
||||||
|
if has('gui_running')
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":menu pup\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"menu pup', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":menu pup\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"menu PopUp.', @:)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" :messages suboptions fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":messages clr\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"messages clr', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":messages clr\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"messages clear', @:)
|
||||||
|
|
||||||
|
" :set option name fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":set brkopt\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"set brkopt', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":set brkopt\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"set breakindentopt', @:)
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":set fixeol\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"set fixendofline', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":set fixeol\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"set fixendofline', @:)
|
||||||
|
|
||||||
|
" :set <term_option>
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":set t_E\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"set t_EC', @:)
|
||||||
|
call feedkeys(":set <t_E\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"set <t_EC>', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":set t_E\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"set t_EC', @:)
|
||||||
|
call feedkeys(":set <t_E\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"set <t_EC>', @:)
|
||||||
|
|
||||||
|
" :packadd directory name fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" shell command name fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" :sign suboptions fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":sign ufe\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"sign ufe', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":sign ufe\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"sign undefine', @:)
|
||||||
|
|
||||||
|
" :syntax suboptions fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":syntax kwd\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"syntax kwd', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":syntax kwd\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"syntax keyword', @:)
|
||||||
|
|
||||||
|
" syntax group name fuzzy completion
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":syntax list mpar\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"syntax list mpar', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":syntax list mpar\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"syntax list MatchParen', @:)
|
||||||
|
|
||||||
|
" :syntime suboptions fuzzy completion
|
||||||
|
if has('profile')
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":syntime clr\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"syntime clr', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":syntime clr\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"syntime clear', @:)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" tag name fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" tag name and file fuzzy completion - NOT supported
|
||||||
|
|
||||||
|
" user names fuzzy completion - how to test this functionality?
|
||||||
|
|
||||||
|
" user defined variable name fuzzy completion
|
||||||
|
let g:SomeVariable=10
|
||||||
|
set wildoptions&
|
||||||
|
call feedkeys(":let SVar\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"let SVar', @:)
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call feedkeys(":let SVar\<Tab>\<C-B>\"\<CR>", 'tx')
|
||||||
|
call assert_equal('"let SomeVariable', @:)
|
||||||
|
|
||||||
|
set wildoptions&
|
||||||
|
%bw!
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -754,6 +754,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
4463,
|
||||||
/**/
|
/**/
|
||||||
4462,
|
4462,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user