mirror of
https://github.com/neovim/neovim.git
synced 2025-09-14 23:38:17 +00:00
Merge pull request #1019 from splinterofchaos/globpath
vim-patch:7.4.279
This commit is contained in:
@@ -6408,7 +6408,7 @@ static struct fst {
|
|||||||
{"getwinposy", 0, 0, f_getwinposy},
|
{"getwinposy", 0, 0, f_getwinposy},
|
||||||
{"getwinvar", 2, 3, f_getwinvar},
|
{"getwinvar", 2, 3, f_getwinvar},
|
||||||
{"glob", 1, 3, f_glob},
|
{"glob", 1, 3, f_glob},
|
||||||
{"globpath", 2, 3, f_globpath},
|
{"globpath", 2, 4, f_globpath},
|
||||||
{"has", 1, 1, f_has},
|
{"has", 1, 1, f_has},
|
||||||
{"has_key", 2, 2, f_has_key},
|
{"has_key", 2, 2, f_has_key},
|
||||||
{"haslocaldir", 0, 0, f_haslocaldir},
|
{"haslocaldir", 0, 0, f_haslocaldir},
|
||||||
@@ -9605,27 +9605,50 @@ static void f_glob(typval_T *argvars, typval_T *rettv)
|
|||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// "globpath()" function
|
||||||
* "globpath()" function
|
|
||||||
*/
|
|
||||||
static void f_globpath(typval_T *argvars, typval_T *rettv)
|
static void f_globpath(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0; // Flags for globpath.
|
||||||
|
int error = false;
|
||||||
|
|
||||||
|
// Return a string, or a list if the optional third argument is non-zero.
|
||||||
|
rettv->v_type = VAR_STRING;
|
||||||
|
|
||||||
|
if (argvars[2].v_type != VAR_UNKNOWN) {
|
||||||
|
// When the optional second argument is non-zero, don't remove matches
|
||||||
|
// for 'wildignore' and don't put matches for 'suffixes' at the end.
|
||||||
|
if (get_tv_number_chk(&argvars[2], &error)) {
|
||||||
|
flags |= WILD_KEEP_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argvars[3].v_type != VAR_UNKNOWN
|
||||||
|
&& get_tv_number_chk(&argvars[3], &error)) {
|
||||||
|
rettv->v_type = VAR_LIST;
|
||||||
|
rettv->vval.v_list = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char_u buf1[NUMBUFLEN];
|
char_u buf1[NUMBUFLEN];
|
||||||
char_u *file = get_tv_string_buf_chk(&argvars[1], buf1);
|
char_u *file = get_tv_string_buf_chk(&argvars[1], buf1);
|
||||||
int error = FALSE;
|
if (file != NULL && !error) {
|
||||||
|
garray_T ga;
|
||||||
|
ga_init(&ga, (int)sizeof(char_u *), 10);
|
||||||
|
globpath(get_tv_string(&argvars[0]), file, &ga, flags);
|
||||||
|
|
||||||
/* When the optional second argument is non-zero, don't remove matches
|
if (rettv->v_type == VAR_STRING) {
|
||||||
* for 'wildignore' and don't put matches for 'suffixes' at the end. */
|
rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n");
|
||||||
if (argvars[2].v_type != VAR_UNKNOWN
|
} else {
|
||||||
&& get_tv_number_chk(&argvars[2], &error))
|
rettv_list_alloc(rettv);
|
||||||
flags |= WILD_KEEP_ALL;
|
for (int i = 0; i < ga.ga_len; i++) {
|
||||||
rettv->v_type = VAR_STRING;
|
list_append_string(rettv->vval.v_list,
|
||||||
if (file == NULL || error)
|
((char_u **)(ga.ga_data))[i], -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ga_clear_strings(&ga);
|
||||||
|
} else {
|
||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
else
|
}
|
||||||
rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file,
|
|
||||||
flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -4051,45 +4051,38 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
|
|||||||
*/
|
*/
|
||||||
static int ExpandRTDir(char_u *pat, int *num_file, char_u ***file, char *dirnames[])
|
static int ExpandRTDir(char_u *pat, int *num_file, char_u ***file, char *dirnames[])
|
||||||
{
|
{
|
||||||
char_u *matches;
|
|
||||||
char_u *s;
|
|
||||||
char_u *e;
|
|
||||||
garray_T ga;
|
|
||||||
int i;
|
|
||||||
int pat_len;
|
|
||||||
|
|
||||||
*num_file = 0;
|
*num_file = 0;
|
||||||
*file = NULL;
|
*file = NULL;
|
||||||
pat_len = (int)STRLEN(pat);
|
size_t pat_len = STRLEN(pat);
|
||||||
|
|
||||||
|
garray_T ga;
|
||||||
ga_init(&ga, (int)sizeof(char *), 10);
|
ga_init(&ga, (int)sizeof(char *), 10);
|
||||||
|
|
||||||
for (i = 0; dirnames[i] != NULL; ++i) {
|
for (int i = 0; dirnames[i] != NULL; i++) {
|
||||||
s = xmalloc(STRLEN(dirnames[i]) + pat_len + 7);
|
size_t size = STRLEN(dirnames[i]) + pat_len + 7;
|
||||||
sprintf((char *)s, "%s/%s*.vim", dirnames[i], pat);
|
char_u *s = xmalloc(size);
|
||||||
matches = globpath(p_rtp, s, 0);
|
snprintf((char *)s, size, "%s/%s*.vim", dirnames[i], pat);
|
||||||
|
globpath(p_rtp, s, &ga, 0);
|
||||||
free(s);
|
free(s);
|
||||||
if (matches == NULL)
|
}
|
||||||
continue;
|
|
||||||
|
|
||||||
for (s = matches; *s != NUL; s = e) {
|
for (int i = 0; i < ga.ga_len; i++) {
|
||||||
e = vim_strchr(s, '\n');
|
char_u *match = ((char_u **)ga.ga_data)[i];
|
||||||
if (e == NULL)
|
char_u *s = match;
|
||||||
e = s + STRLEN(s);
|
char_u *e = s + STRLEN(s);
|
||||||
ga_grow(&ga, 1);
|
if (e - s > 4 && STRNICMP(e - 4, ".vim", 4) == 0) {
|
||||||
if (e - 4 > s && STRNICMP(e - 4, ".vim", 4) == 0) {
|
e -= 4;
|
||||||
for (s = e - 4; s > matches; mb_ptr_back(matches, s))
|
for (s = e; s > match; mb_ptr_back(match, s)) {
|
||||||
if (*s == '\n' || vim_ispathsep(*s))
|
if (vim_ispathsep(*s)) {
|
||||||
break;
|
break;
|
||||||
++s;
|
|
||||||
((char_u **)ga.ga_data)[ga.ga_len] =
|
|
||||||
vim_strnsave(s, (int)(e - s - 4));
|
|
||||||
++ga.ga_len;
|
|
||||||
}
|
}
|
||||||
if (*e != NUL)
|
|
||||||
++e;
|
|
||||||
}
|
}
|
||||||
free(matches);
|
s++;
|
||||||
|
*e = NUL;
|
||||||
|
memmove(match, s, e - s + 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (GA_EMPTY(&ga))
|
if (GA_EMPTY(&ga))
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
@@ -4103,60 +4096,43 @@ static int ExpandRTDir(char_u *pat, int *num_file, char_u ***file, char *dirname
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/// Expand `file` for all comma-separated directories in `path`.
|
||||||
* Expand "file" for all comma-separated directories in "path".
|
/// Adds matches to `ga`.
|
||||||
* Returns an allocated string with all matches concatenated, separated by
|
void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options)
|
||||||
* newlines. Returns NULL for an error or no matches.
|
|
||||||
*/
|
|
||||||
char_u *globpath(char_u *path, char_u *file, int expand_options)
|
|
||||||
{
|
{
|
||||||
expand_T xpc;
|
expand_T xpc;
|
||||||
garray_T ga;
|
|
||||||
int i;
|
|
||||||
int len;
|
|
||||||
int num_p;
|
|
||||||
char_u **p;
|
|
||||||
char_u *cur = NULL;
|
|
||||||
|
|
||||||
char_u *buf = xmalloc(MAXPATHL);
|
|
||||||
|
|
||||||
ExpandInit(&xpc);
|
ExpandInit(&xpc);
|
||||||
xpc.xp_context = EXPAND_FILES;
|
xpc.xp_context = EXPAND_FILES;
|
||||||
|
|
||||||
ga_init(&ga, 1, 100);
|
char_u *buf = xmalloc(MAXPATHL);
|
||||||
|
|
||||||
/* Loop over all entries in {path}. */
|
// Loop over all entries in {path}.
|
||||||
while (*path != NUL) {
|
while (*path != NUL) {
|
||||||
/* Copy one item of the path to buf[] and concatenate the file name. */
|
// Copy one item of the path to buf[] and concatenate the file name.
|
||||||
copy_option_part(&path, buf, MAXPATHL, ",");
|
copy_option_part(&path, buf, MAXPATHL, ",");
|
||||||
if (STRLEN(buf) + STRLEN(file) + 2 < MAXPATHL) {
|
if (STRLEN(buf) + STRLEN(file) + 2 < MAXPATHL) {
|
||||||
add_pathsep(buf);
|
add_pathsep(buf);
|
||||||
STRCAT(buf, file);
|
STRCAT(buf, file); // NOLINT
|
||||||
|
|
||||||
|
char_u **p;
|
||||||
|
int num_p;
|
||||||
if (ExpandFromContext(&xpc, buf, &num_p, &p,
|
if (ExpandFromContext(&xpc, buf, &num_p, &p,
|
||||||
WILD_SILENT|expand_options) != FAIL && num_p > 0) {
|
WILD_SILENT|expand_options) != FAIL && num_p > 0) {
|
||||||
ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT|expand_options);
|
ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT|expand_options);
|
||||||
for (len = 0, i = 0; i < num_p; ++i)
|
|
||||||
len += (int)STRLEN(p[i]) + 1;
|
|
||||||
|
|
||||||
/* Concatenate new results to previous ones. */
|
// Concatenate new results to previous ones.
|
||||||
ga_grow(&ga, len);
|
ga_grow(ga, num_p);
|
||||||
cur = (char_u *)ga.ga_data + ga.ga_len;
|
for (int i = 0; i < num_p; i++) {
|
||||||
for (i = 0; i < num_p; ++i) {
|
((char_u **)ga->ga_data)[ga->ga_len] = vim_strsave(p[i]);
|
||||||
STRCPY(cur, p[i]);
|
ga->ga_len++;
|
||||||
cur += STRLEN(p[i]);
|
|
||||||
*cur++ = '\n';
|
|
||||||
}
|
}
|
||||||
ga.ga_len += len;
|
|
||||||
|
|
||||||
FreeWild(num_p, p);
|
FreeWild(num_p, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cur != NULL)
|
|
||||||
*--cur = 0; /* Replace trailing newline with NUL */
|
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return (char_u *)ga.ga_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -133,6 +133,7 @@ void ga_remove_duplicate_strings(garray_T *gap)
|
|||||||
/// strings with sep as separator.
|
/// strings with sep as separator.
|
||||||
///
|
///
|
||||||
/// @param gap
|
/// @param gap
|
||||||
|
/// @param sep
|
||||||
///
|
///
|
||||||
/// @returns the concatenated strings
|
/// @returns the concatenated strings
|
||||||
char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)
|
char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)
|
||||||
|
@@ -926,9 +926,6 @@ expand_in_path (
|
|||||||
{
|
{
|
||||||
char_u *curdir;
|
char_u *curdir;
|
||||||
garray_T path_ga;
|
garray_T path_ga;
|
||||||
char_u *files = NULL;
|
|
||||||
char_u *s; /* start */
|
|
||||||
char_u *e; /* end */
|
|
||||||
char_u *paths = NULL;
|
char_u *paths = NULL;
|
||||||
|
|
||||||
curdir = xmalloc(MAXPATHL);
|
curdir = xmalloc(MAXPATHL);
|
||||||
@@ -943,28 +940,8 @@ expand_in_path (
|
|||||||
paths = ga_concat_strings(&path_ga);
|
paths = ga_concat_strings(&path_ga);
|
||||||
ga_clear_strings(&path_ga);
|
ga_clear_strings(&path_ga);
|
||||||
|
|
||||||
files = globpath(paths, pattern, (flags & EW_ICASE) ? WILD_ICASE : 0);
|
globpath(paths, pattern, gap, (flags & EW_ICASE) ? WILD_ICASE : 0);
|
||||||
free(paths);
|
free(paths);
|
||||||
if (files == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Copy each path in files into gap */
|
|
||||||
s = e = files;
|
|
||||||
while (*s != NUL) {
|
|
||||||
while (*e != '\n' && *e != NUL)
|
|
||||||
e++;
|
|
||||||
if (*e == NUL) {
|
|
||||||
addfile(gap, s, flags);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
/* *e is '\n' */
|
|
||||||
*e = NUL;
|
|
||||||
addfile(gap, s, flags);
|
|
||||||
e++;
|
|
||||||
s = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(files);
|
|
||||||
|
|
||||||
return gap->ga_len;
|
return gap->ga_len;
|
||||||
}
|
}
|
||||||
|
@@ -8,12 +8,15 @@ STARTTEST
|
|||||||
:" consistent sorting of file names
|
:" consistent sorting of file names
|
||||||
:set nofileignorecase
|
:set nofileignorecase
|
||||||
:e test.out
|
:e test.out
|
||||||
:put =glob('Xxx\{')
|
:$put =glob('Xxx\{')
|
||||||
:put =glob('Xxx\$')
|
:$put =glob('Xxx\$')
|
||||||
:w! Xxx{
|
:w! Xxx{
|
||||||
:w! Xxx\$
|
:w! Xxx\$
|
||||||
:put =glob('Xxx\{')
|
:$put =glob('Xxx\{')
|
||||||
:put =glob('Xxx\$')
|
:$put =glob('Xxx\$')
|
||||||
|
:"
|
||||||
|
:$put =string(globpath('sautest/autoload', '*.vim'))
|
||||||
|
:$put =string(globpath('sautest/autoload', '*.vim', 0, 1))
|
||||||
:w
|
:w
|
||||||
:qa!
|
:qa!
|
||||||
ENDTEST
|
ENDTEST
|
||||||
|
@@ -3,3 +3,6 @@
|
|||||||
|
|
||||||
Xxx{
|
Xxx{
|
||||||
Xxx$
|
Xxx$
|
||||||
|
'sautest/autoload/Test104.vim
|
||||||
|
sautest/autoload/footest.vim'
|
||||||
|
['sautest/autoload/Test104.vim', 'sautest/autoload/footest.vim']
|
||||||
|
@@ -316,7 +316,7 @@ static int included_patches[] = {
|
|||||||
282,
|
282,
|
||||||
281,
|
281,
|
||||||
280,
|
280,
|
||||||
//279,
|
279,
|
||||||
//278,
|
//278,
|
||||||
277,
|
277,
|
||||||
276,
|
276,
|
||||||
|
Reference in New Issue
Block a user