mirror of
https://github.com/neovim/neovim.git
synced 2025-09-15 15:58:17 +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:
@@ -88,6 +88,7 @@
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/search.h"
|
||||
#include "nvim/sign.h"
|
||||
#include "nvim/spell.h"
|
||||
#include "nvim/statusline.h"
|
||||
@@ -2337,7 +2338,6 @@ int ExpandBufnames(char *pat, int *num_file, char ***file, int options)
|
||||
int round;
|
||||
char *p;
|
||||
int attempt;
|
||||
char *patc;
|
||||
bufmatch_T *matches = NULL;
|
||||
|
||||
*num_file = 0; // return values in case of FAIL
|
||||
@@ -2347,31 +2347,40 @@ int ExpandBufnames(char *pat, int *num_file, char ***file, int options)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// Make a copy of "pat" and change "^" to "\(^\|[\/]\)".
|
||||
if (*pat == '^') {
|
||||
patc = xmalloc(strlen(pat) + 11);
|
||||
STRCPY(patc, "\\(^\\|[\\/]\\)");
|
||||
STRCPY(patc + 11, pat + 1);
|
||||
} else {
|
||||
patc = pat;
|
||||
const bool fuzzy = cmdline_fuzzy_complete(pat);
|
||||
|
||||
char *patc = NULL;
|
||||
// Make a copy of "pat" and change "^" to "\(^\|[\/]\)" (if doing regular
|
||||
// expression matching)
|
||||
if (!fuzzy) {
|
||||
if (*pat == '^') {
|
||||
patc = xmalloc(strlen(pat) + 11);
|
||||
STRCPY(patc, "\\(^\\|[\\/]\\)");
|
||||
STRCPY(patc + 11, pat + 1);
|
||||
} else {
|
||||
patc = pat;
|
||||
}
|
||||
}
|
||||
|
||||
fuzmatch_str_T *fuzmatch = NULL;
|
||||
// attempt == 0: try match with '\<', match at start of word
|
||||
// attempt == 1: try match without '\<', match anywhere
|
||||
for (attempt = 0; attempt <= 1; attempt++) {
|
||||
if (attempt > 0 && patc == pat) {
|
||||
break; // there was no anchor, no need to try again
|
||||
}
|
||||
|
||||
for (attempt = 0; attempt <= (fuzzy ? 0 : 1); attempt++) {
|
||||
regmatch_T regmatch;
|
||||
regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
|
||||
if (regmatch.regprog == NULL) {
|
||||
if (patc != pat) {
|
||||
xfree(patc);
|
||||
if (!fuzzy) {
|
||||
if (attempt > 0 && patc == pat) {
|
||||
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) {
|
||||
xfree(patc);
|
||||
}
|
||||
return FAIL;
|
||||
}
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
int score = 0;
|
||||
// round == 1: Count the matches.
|
||||
// round == 2: Build the array to keep the matches.
|
||||
for (round = 1; round <= 2; round++) {
|
||||
@@ -2387,7 +2396,23 @@ int ExpandBufnames(char *pat, int *num_file, char ***file, int options)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
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 (round == 1) {
|
||||
count++;
|
||||
@@ -2397,12 +2422,20 @@ int ExpandBufnames(char *pat, int *num_file, char ***file, int options)
|
||||
} else {
|
||||
p = xstrdup(p);
|
||||
}
|
||||
if (matches != NULL) {
|
||||
matches[count].buf = buf;
|
||||
matches[count].match = p;
|
||||
count++;
|
||||
|
||||
if (!fuzzy) {
|
||||
if (matches != NULL) {
|
||||
matches[count].buf = buf;
|
||||
matches[count].match = p;
|
||||
count++;
|
||||
} else {
|
||||
(*file)[count++] = p;
|
||||
}
|
||||
} else {
|
||||
(*file)[count++] = p;
|
||||
fuzmatch[count].idx = count;
|
||||
fuzmatch[count].str = p;
|
||||
fuzmatch[count].score = score;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2411,40 +2444,50 @@ int ExpandBufnames(char *pat, int *num_file, char ***file, int options)
|
||||
break;
|
||||
}
|
||||
if (round == 1) {
|
||||
*file = xmalloc((size_t)count * sizeof(**file));
|
||||
|
||||
if (options & WILD_BUFLASTUSED) {
|
||||
matches = xmalloc((size_t)count * sizeof(*matches));
|
||||
if (!fuzzy) {
|
||||
*file = xmalloc((size_t)count * sizeof(**file));
|
||||
if (options & WILD_BUFLASTUSED) {
|
||||
matches = xmalloc((size_t)count * sizeof(*matches));
|
||||
}
|
||||
} else {
|
||||
fuzmatch = xmalloc((size_t)count * sizeof(fuzmatch_str_T));
|
||||
}
|
||||
}
|
||||
}
|
||||
vim_regfree(regmatch.regprog);
|
||||
if (count) { // match(es) found, break here
|
||||
break;
|
||||
|
||||
if (!fuzzy) {
|
||||
vim_regfree(regmatch.regprog);
|
||||
if (count) { // match(es) found, break here
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (patc != pat) {
|
||||
if (!fuzzy && patc != pat) {
|
||||
xfree(patc);
|
||||
}
|
||||
|
||||
if (matches != NULL) {
|
||||
if (count > 1) {
|
||||
qsort(matches, (size_t)count, sizeof(bufmatch_T), buf_time_compare);
|
||||
}
|
||||
if (!fuzzy) {
|
||||
if (matches != NULL) {
|
||||
if (count > 1) {
|
||||
qsort(matches, (size_t)count, sizeof(bufmatch_T), buf_time_compare);
|
||||
}
|
||||
|
||||
// if the current buffer is first in the list, place it at the end
|
||||
if (matches[0].buf == curbuf) {
|
||||
for (int i = 1; i < count; i++) {
|
||||
(*file)[i - 1] = matches[i].match;
|
||||
}
|
||||
(*file)[count - 1] = matches[0].match;
|
||||
} else {
|
||||
for (int i = 0; i < count; i++) {
|
||||
(*file)[i] = matches[i].match;
|
||||
// if the current buffer is first in the list, place it at the end
|
||||
if (matches[0].buf == curbuf) {
|
||||
for (int i = 1; i < count; i++) {
|
||||
(*file)[i - 1] = matches[i].match;
|
||||
}
|
||||
(*file)[count - 1] = matches[0].match;
|
||||
} else {
|
||||
for (int i = 0; i < count; i++) {
|
||||
(*file)[i] = matches[i].match;
|
||||
}
|
||||
}
|
||||
xfree(matches);
|
||||
}
|
||||
xfree(matches);
|
||||
} else {
|
||||
fuzzymatches_to_strmatches(fuzmatch, file, count, false);
|
||||
}
|
||||
|
||||
*num_file = count;
|
||||
|
Reference in New Issue
Block a user