diff options
author | Shougo <Shougo.Matsu@gmail.com> | 2022-04-03 21:27:46 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-03 20:27:46 +0800 |
commit | e9e16655af1bacd4b1499fed00a142512c120710 (patch) | |
tree | 06a77f45aaf25b49c4b907ed52b8ddf48ec794f2 /src/nvim/eval | |
parent | 6786b6afade97771027fda3c1438969def320cc5 (diff) | |
download | rneovim-e9e16655af1bacd4b1499fed00a142512c120710.tar.gz rneovim-e9e16655af1bacd4b1499fed00a142512c120710.tar.bz2 rneovim-e9e16655af1bacd4b1499fed00a142512c120710.zip |
[RFC] vim-patch:8.1.1378: delete() can not handle a file name that looks li… (#16268)
Problem: Delete() can not handle a file name that looks like a pattern.
Solution: Use readdir() instead of appending "/*" and expanding wildcards.
(Ken Takata, closes vim/vim#4424, closes vim/vim#696)
https://github.com/vim/vim/commit/701ff0a3e53d253d7300c385e582659bbff7860d
Cherry-pick a change to Test_delete_rf() from patch 8.1.1921.
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Diffstat (limited to 'src/nvim/eval')
-rw-r--r-- | src/nvim/eval/funcs.c | 62 |
1 files changed, 15 insertions, 47 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 267b8a433b..92672be8d0 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -6702,15 +6702,21 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -/// Evaluate "expr" for readdir(). -static varnumber_T readdir_checkitem(typval_T *expr, const char *name) +/// Evaluate "expr" (= "context") for readdir(). +static varnumber_T readdir_checkitem(void *context, const char *name) + FUNC_ATTR_NONNULL_ALL { + typval_T *expr = (typval_T *)context; typval_T save_val; typval_T rettv; typval_T argv[2]; varnumber_T retval = 0; bool error = false; + if (expr->v_type == VAR_UNKNOWN) { + return 1; + } + prepare_vimvar(VV_VAL, &save_val); set_vim_var_string(VV_VAL, name, -1); argv[0].v_type = VAR_STRING; @@ -6736,54 +6742,16 @@ theend: /// "readdir()" function static void f_readdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - typval_T *expr; - const char *path; - garray_T ga; - Directory dir; - tv_list_alloc_ret(rettv, kListLenUnknown); - path = tv_get_string(&argvars[0]); - expr = &argvars[1]; - ga_init(&ga, (int)sizeof(char *), 20); - - if (!os_scandir(&dir, path)) { - smsg(_(e_notopen), path); - } else { - for (;;) { - bool ignore; - - path = os_scandir_next(&dir); - if (path == NULL) { - break; - } - - ignore = (path[0] == '.' - && (path[1] == NUL || (path[1] == '.' && path[2] == NUL))); - if (!ignore && expr->v_type != VAR_UNKNOWN) { - varnumber_T r = readdir_checkitem(expr, path); - if (r < 0) { - break; - } - if (r == 0) { - ignore = true; - } - } - - if (!ignore) { - ga_grow(&ga, 1); - ((char **)ga.ga_data)[ga.ga_len++] = xstrdup(path); - } - } - - os_closedir(&dir); - } - - if (rettv->vval.v_list != NULL && ga.ga_len > 0) { - sort_strings((char_u **)ga.ga_data, ga.ga_len); + const char *path = tv_get_string(&argvars[0]); + typval_T *expr = &argvars[1]; + garray_T ga; + int ret = readdir_core(&ga, path, (void *)expr, readdir_checkitem); + if (ret == OK && ga.ga_len > 0) { for (int i = 0; i < ga.ga_len; i++) { - path = ((const char **)ga.ga_data)[i]; - tv_list_append_string(rettv->vval.v_list, path, -1); + const char *p = ((const char **)ga.ga_data)[i]; + tv_list_append_string(rettv->vval.v_list, p, -1); } } ga_clear_strings(&ga); |