From 6644786db078e019426f90cf85da50e3fa1b6a67 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 26 Jan 2023 09:44:15 +0800 Subject: vim-patch:9.0.1227: no cmdline completion for :runtime Problem: No cmdline completion for :runtime. Solution: Add completion for :runtime. (closes vim/vim#11853, closes vim/vim#11447) Improve the resulting matches. https://github.com/vim/vim/commit/a6759381a590b2d395e05b109ca9ccfc356be5a8 --- src/nvim/runtime.c | 70 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 12 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 24500b80b9..068a43c790 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1194,11 +1194,22 @@ int ExpandRTDir(char *pat, int flags, int *num_file, char ***file, char *dirname // TODO(bfredl): this is bullshit, expandpath should not reinvent path logic. for (int i = 0; dirnames[i] != NULL; i++) { - size_t size = strlen(dirnames[i]) + pat_len + 16; - char *s = xmalloc(size); - snprintf(s, size, "%s/%s*.\\(vim\\|lua\\)", dirnames[i], pat); - globpath(p_rtp, s, &ga, 0); - xfree(s); + size_t size = strlen(dirnames[i]) + pat_len * 2 + 26; + char *buf = xmalloc(size); + if (*dirnames[i] == NUL) { + // empty dir used for :runtime + if (path_tail(pat) == pat) { + // no path separator, match dir names and script files + snprintf(buf, size, "\\(%s*.\\(vim\\|lua\\)\\)\\|\\(%s*\\)", pat, pat); + } else { + // has path separator, match script files + snprintf(buf, size, "%s*.vim", pat); + } + } else { + snprintf(buf, size, "%s/%s*.\\(vim\\|lua\\)", dirnames[i], pat); + } + globpath(p_rtp, buf, &ga, 0); + xfree(buf); } if (flags & DIP_START) { @@ -1241,18 +1252,53 @@ int ExpandRTDir(char *pat, int flags, int *num_file, char ***file, char *dirname char *match = ((char **)ga.ga_data)[i]; char *s = match; char *e = s + strlen(s); + char *res_start = s; + if ((flags & DIP_PRNEXT) != 0) { + char *p = strstr(match, pat); + if (p != NULL) { + // Drop what comes before "pat" in the match, so that for + // match "/long/path/syntax/cpp.vim" with pattern + // "syntax/cp" we only keep "syntax/cpp.vim". + res_start = p; + } + } + if (e - s > 4 && (STRNICMP(e - 4, ".vim", 4) == 0 || STRNICMP(e - 4, ".lua", 4) == 0)) { - e -= 4; - for (s = e; s > match; MB_PTR_BACK(match, s)) { - if (vim_ispathsep(*s)) { - break; + if (res_start == s) { + // Only keep the file name. + // Remove file ext only if flag DIP_PRNEXT is not present. + if ((flags & DIP_PRNEXT) == 0) { + e -= 4; + } + for (s = e; s > match; MB_PTR_BACK(match, s)) { + if (s < match) { + break; + } + if (vim_ispathsep(*s)) { + res_start = s + 1; + break; + } } } - s++; + *e = NUL; - assert((e - s) + 1 >= 0); - memmove(match, s, (size_t)(e - s) + 1); + } + + if (res_start > match) { + assert((e - res_start) + 1 >= 0); + memmove(match, res_start, (size_t)(e - res_start) + 1); + } + + // remove entries that look like backup files + if (e > s && e[-1] == '~') { + xfree(match); + char **fnames = (char **)ga.ga_data; + for (int j = i + 1; j < ga.ga_len; ++j) { + fnames[j - 1] = fnames[j]; + } + ga.ga_len--; + i--; } } -- cgit From 6320c91c50e4c0ee5c366241f9a413c4edbfdad8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 26 Jan 2023 09:58:27 +0800 Subject: vim-patch:9.0.1231: completion of :runtime does not handle {where} argument Problem: Completion of :runtime does not handle {where} argument. Solution: Parse the {where} argument. (closes vim/vim#11863) https://github.com/vim/vim/commit/3770f4c9cde7b5fcd10b6fa2e665cd0b69450fb2 --- src/nvim/runtime.c | 205 ++++++++++++++++++++++++++--------------------------- 1 file changed, 102 insertions(+), 103 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 068a43c790..129d41ed22 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -208,31 +208,65 @@ void runtime_init(void) uv_mutex_init(&runtime_search_path_mutex); } +/// Get DIP_ flags from the [what] argument of a :runtime command. +/// "*argp" is advanced to after the [what] argument. +static int get_runtime_cmd_flags(char **argp) +{ + char *arg = *argp; + char *p = skiptowhite(arg); + size_t what_len = (size_t)(p - arg); + + if (what_len == 0) { + return 0; + } + + if (strncmp(arg, "START", what_len) == 0) { + *argp = skipwhite(arg + what_len); + return DIP_START + DIP_NORTP; + } + if (strncmp(arg, "OPT", what_len) == 0) { + *argp = skipwhite(arg + what_len); + return DIP_OPT + DIP_NORTP; + } + if (strncmp(arg, "PACK", what_len) == 0) { + *argp = skipwhite(arg + what_len); + return DIP_START + DIP_OPT + DIP_NORTP; + } + if (strncmp(arg, "ALL", what_len) == 0) { + *argp = skipwhite(arg + what_len); + return DIP_START + DIP_OPT; + } + + return 0; +} + /// ":runtime [what] {name}" void ex_runtime(exarg_T *eap) { char *arg = eap->arg; - char *p = skiptowhite(arg); - size_t len = (size_t)(p - arg); int flags = eap->forceit ? DIP_ALL : 0; - if (strncmp(arg, "START", len) == 0) { - flags += DIP_START + DIP_NORTP; - arg = skipwhite(arg + len); - } else if (strncmp(arg, "OPT", len) == 0) { - flags += DIP_OPT + DIP_NORTP; - arg = skipwhite(arg + len); - } else if (strncmp(arg, "PACK", len) == 0) { - flags += DIP_START + DIP_OPT + DIP_NORTP; - arg = skipwhite(arg + len); - } else if (strncmp(arg, "ALL", len) == 0) { - flags += DIP_START + DIP_OPT; - arg = skipwhite(arg + len); - } - + flags += get_runtime_cmd_flags(&arg); source_runtime(arg, flags); } +static int runtime_expand_flags; + +/// Set the completion context for the :runtime command. +void set_context_in_runtime_cmd(expand_T *xp, const char *arg) +{ + runtime_expand_flags = DIP_KEEPEXT + get_runtime_cmd_flags((char **)&arg); + xp->xp_context = EXPAND_RUNTIME; + xp->xp_pattern = (char *)arg; +} + +/// Handle command line completion for :runtime command. +int expand_runtime_cmd(char *pat, int *numMatches, char ***matches) +{ + char *directories[] = {"", NULL}; + return ExpandRTDir(pat, runtime_expand_flags, numMatches, matches, directories); +} + static void source_callback(char *fname, void *cookie) { (void)do_source(fname, false, DOSO_NONE); @@ -1194,57 +1228,53 @@ int ExpandRTDir(char *pat, int flags, int *num_file, char ***file, char *dirname // TODO(bfredl): this is bullshit, expandpath should not reinvent path logic. for (int i = 0; dirnames[i] != NULL; i++) { - size_t size = strlen(dirnames[i]) + pat_len * 2 + 26; - char *buf = xmalloc(size); - if (*dirnames[i] == NUL) { - // empty dir used for :runtime - if (path_tail(pat) == pat) { - // no path separator, match dir names and script files - snprintf(buf, size, "\\(%s*.\\(vim\\|lua\\)\\)\\|\\(%s*\\)", pat, pat); - } else { - // has path separator, match script files - snprintf(buf, size, "%s*.vim", pat); - } + const size_t buf_len = strlen(dirnames[i]) + pat_len + 31; + char *const buf = xmalloc(buf_len); + char *const tail = buf + 15; + const size_t tail_buflen = buf_len - 15; + int glob_flags = 0; + bool expand_dirs = false; + + if (*dirnames[i] == NUL) { // empty dir used for :runtime + snprintf(tail, tail_buflen, "%s*.\\(vim\\|lua\\)", pat); } else { - snprintf(buf, size, "%s/%s*.\\(vim\\|lua\\)", dirnames[i], pat); + snprintf(tail, tail_buflen, "%s/%s*.\\(vim\\|lua\\)", dirnames[i], pat); } - globpath(p_rtp, buf, &ga, 0); - xfree(buf); - } - if (flags & DIP_START) { - for (int i = 0; dirnames[i] != NULL; i++) { - size_t size = strlen(dirnames[i]) + pat_len + 31; - char *s = xmalloc(size); - snprintf(s, size, "pack/*/start/*/%s/%s*.\\(vim\\|lua\\)", dirnames[i], pat); // NOLINT - globpath(p_pp, s, &ga, 0); - xfree(s); +expand: + if ((flags & DIP_NORTP) == 0) { + globpath(p_rtp, tail, &ga, glob_flags, expand_dirs); } - for (int i = 0; dirnames[i] != NULL; i++) { - size_t size = strlen(dirnames[i]) + pat_len + 31; - char *s = xmalloc(size); - snprintf(s, size, "start/*/%s/%s*.\\(vim\\|lua\\)", dirnames[i], pat); // NOLINT - globpath(p_pp, s, &ga, 0); - xfree(s); + if (flags & DIP_START) { + memcpy(tail - 15, "pack/*/start/*/", 15); // NOLINT + globpath(p_pp, tail - 15, &ga, glob_flags, expand_dirs); + memcpy(tail - 8, "start/*/", 8); // NOLINT + globpath(p_pp, tail - 8, &ga, glob_flags, expand_dirs); } - } - if (flags & DIP_OPT) { - for (int i = 0; dirnames[i] != NULL; i++) { - size_t size = strlen(dirnames[i]) + pat_len + 29; - char *s = xmalloc(size); - snprintf(s, size, "pack/*/opt/*/%s/%s*.\\(vim\\|lua\\)", dirnames[i], pat); // NOLINT - globpath(p_pp, s, &ga, 0); - xfree(s); + if (flags & DIP_OPT) { + memcpy(tail - 13, "pack/*/opt/*/", 13); // NOLINT + globpath(p_pp, tail - 13, &ga, glob_flags, expand_dirs); + memcpy(tail - 6, "opt/*/", 6); // NOLINT + globpath(p_pp, tail - 6, &ga, glob_flags, expand_dirs); } - for (int i = 0; dirnames[i] != NULL; i++) { - size_t size = strlen(dirnames[i]) + pat_len + 29; - char *s = xmalloc(size); - snprintf(s, size, "opt/*/%s/%s*.\\(vim\\|lua\\)", dirnames[i], pat); // NOLINT - globpath(p_pp, s, &ga, 0); - xfree(s); + if (*dirnames[i] == NUL && !expand_dirs) { + // expand dir names in another round + snprintf(tail, tail_buflen, "%s*", pat); + glob_flags = WILD_ADD_SLASH; + expand_dirs = true; + goto expand; + } + + xfree(buf); + } + + int pat_pathsep_cnt = 0; + for (size_t i = 0; i < pat_len; i++) { + if (vim_ispathsep(pat[i])) { + pat_pathsep_cnt++; } } @@ -1252,54 +1282,23 @@ int ExpandRTDir(char *pat, int flags, int *num_file, char ***file, char *dirname char *match = ((char **)ga.ga_data)[i]; char *s = match; char *e = s + strlen(s); - char *res_start = s; - if ((flags & DIP_PRNEXT) != 0) { - char *p = strstr(match, pat); - if (p != NULL) { - // Drop what comes before "pat" in the match, so that for - // match "/long/path/syntax/cpp.vim" with pattern - // "syntax/cp" we only keep "syntax/cpp.vim". - res_start = p; - } - } - - if (e - s > 4 && (STRNICMP(e - 4, ".vim", 4) == 0 - || STRNICMP(e - 4, ".lua", 4) == 0)) { - if (res_start == s) { - // Only keep the file name. - // Remove file ext only if flag DIP_PRNEXT is not present. - if ((flags & DIP_PRNEXT) == 0) { - e -= 4; - } - for (s = e; s > match; MB_PTR_BACK(match, s)) { - if (s < match) { - break; - } - if (vim_ispathsep(*s)) { - res_start = s + 1; - break; - } - } - } - + if (e - s > 4 && (flags & DIP_KEEPEXT) == 0 + && (STRNICMP(e - 4, ".vim", 4) == 0 + || STRNICMP(e - 4, ".lua", 4) == 0)) { + e -= 4; *e = NUL; } - if (res_start > match) { - assert((e - res_start) + 1 >= 0); - memmove(match, res_start, (size_t)(e - res_start) + 1); - } - - // remove entries that look like backup files - if (e > s && e[-1] == '~') { - xfree(match); - char **fnames = (char **)ga.ga_data; - for (int j = i + 1; j < ga.ga_len; ++j) { - fnames[j - 1] = fnames[j]; + int match_pathsep_cnt = (e > s && e[-1] == '/') ? -1 : 0; + for (s = e; s > match; MB_PTR_BACK(match, s)) { + if (vim_ispathsep(*s) && ++match_pathsep_cnt > pat_pathsep_cnt) { + break; } - ga.ga_len--; - i--; } + s++; + *e = NUL; + assert((e - s) + 1 >= 0); + memmove(match, s, (size_t)(e - s) + 1); } if (GA_EMPTY(&ga)) { @@ -1329,9 +1328,9 @@ int ExpandPackAddDir(char *pat, int *num_file, char ***file) size_t buflen = pat_len + 26; char *s = xmalloc(buflen); snprintf(s, buflen, "pack/*/opt/%s*", pat); // NOLINT - globpath(p_pp, s, &ga, 0); + globpath(p_pp, s, &ga, 0, true); snprintf(s, buflen, "opt/%s*", pat); // NOLINT - globpath(p_pp, s, &ga, 0); + globpath(p_pp, s, &ga, 0, true); xfree(s); for (int i = 0; i < ga.ga_len; i++) { -- cgit From f03f6263bb3eb0b28b759292cb6ef4465a05cafe Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 26 Jan 2023 10:38:53 +0800 Subject: vim-patch:9.0.1238: :runtime completion can be further improved Problem: :runtime completion can be further improved. Solution: Also complete the {where} argument values and adjust the completion for that. (closes vim/vim#11874) https://github.com/vim/vim/commit/5c8771bc5a2be123ab8e6325fa60ed524e8efb09 --- src/nvim/runtime.c | 151 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 58 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 129d41ed22..b071e10cf9 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -26,6 +26,7 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" +#include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" @@ -208,45 +209,43 @@ void runtime_init(void) uv_mutex_init(&runtime_search_path_mutex); } -/// Get DIP_ flags from the [what] argument of a :runtime command. -/// "*argp" is advanced to after the [what] argument. -static int get_runtime_cmd_flags(char **argp) +/// Get DIP_ flags from the [where] argument of a :runtime command. +/// "*argp" is advanced to after the [where] argument. +static int get_runtime_cmd_flags(char **argp, size_t where_len) { char *arg = *argp; - char *p = skiptowhite(arg); - size_t what_len = (size_t)(p - arg); - if (what_len == 0) { + if (where_len == 0) { return 0; } - if (strncmp(arg, "START", what_len) == 0) { - *argp = skipwhite(arg + what_len); + if (strncmp(arg, "START", where_len) == 0) { + *argp = skipwhite(arg + where_len); return DIP_START + DIP_NORTP; } - if (strncmp(arg, "OPT", what_len) == 0) { - *argp = skipwhite(arg + what_len); + if (strncmp(arg, "OPT", where_len) == 0) { + *argp = skipwhite(arg + where_len); return DIP_OPT + DIP_NORTP; } - if (strncmp(arg, "PACK", what_len) == 0) { - *argp = skipwhite(arg + what_len); + if (strncmp(arg, "PACK", where_len) == 0) { + *argp = skipwhite(arg + where_len); return DIP_START + DIP_OPT + DIP_NORTP; } - if (strncmp(arg, "ALL", what_len) == 0) { - *argp = skipwhite(arg + what_len); + if (strncmp(arg, "ALL", where_len) == 0) { + *argp = skipwhite(arg + where_len); return DIP_START + DIP_OPT; } return 0; } -/// ":runtime [what] {name}" +/// ":runtime [where] {name}" void ex_runtime(exarg_T *eap) { char *arg = eap->arg; int flags = eap->forceit ? DIP_ALL : 0; - - flags += get_runtime_cmd_flags(&arg); + char *p = skiptowhite(arg); + flags += get_runtime_cmd_flags(&arg, (size_t)(p - arg)); source_runtime(arg, flags); } @@ -255,18 +254,13 @@ static int runtime_expand_flags; /// Set the completion context for the :runtime command. void set_context_in_runtime_cmd(expand_T *xp, const char *arg) { - runtime_expand_flags = DIP_KEEPEXT + get_runtime_cmd_flags((char **)&arg); + char *p = skiptowhite(arg); + runtime_expand_flags + = *p != NUL ? get_runtime_cmd_flags((char **)&arg, (size_t)(p - arg)) : 0; xp->xp_context = EXPAND_RUNTIME; xp->xp_pattern = (char *)arg; } -/// Handle command line completion for :runtime command. -int expand_runtime_cmd(char *pat, int *numMatches, char ***matches) -{ - char *directories[] = {"", NULL}; - return ExpandRTDir(pat, runtime_expand_flags, numMatches, matches, directories); -} - static void source_callback(char *fname, void *cookie) { (void)do_source(fname, false, DOSO_NONE); @@ -1209,23 +1203,9 @@ void ex_packadd(exarg_T *eap) } } -/// Expand color scheme, compiler or filetype names. -/// Search from 'runtimepath': -/// 'runtimepath'/{dirnames}/{pat}.(vim|lua) -/// When "flags" has DIP_START: search also from "start" of 'packpath': -/// 'packpath'/pack/*/start/*/{dirnames}/{pat}.(vim|lua) -/// When "flags" has DIP_OPT: search also from "opt" of 'packpath': -/// 'packpath'/pack/*/opt/*/{dirnames}/{pat}.(vim|lua) -/// "dirnames" is an array with one or more directory names. -int ExpandRTDir(char *pat, int flags, int *num_file, char ***file, char *dirnames[]) +static void ExpandRTDir_int(char *pat, size_t pat_len, int flags, bool keep_ext, garray_T *gap, + char *dirnames[]) { - *num_file = 0; - *file = NULL; - size_t pat_len = strlen(pat); - - garray_T ga; - ga_init(&ga, (int)sizeof(char *), 10); - // TODO(bfredl): this is bullshit, expandpath should not reinvent path logic. for (int i = 0; dirnames[i] != NULL; i++) { const size_t buf_len = strlen(dirnames[i]) + pat_len + 31; @@ -1243,21 +1223,21 @@ int ExpandRTDir(char *pat, int flags, int *num_file, char ***file, char *dirname expand: if ((flags & DIP_NORTP) == 0) { - globpath(p_rtp, tail, &ga, glob_flags, expand_dirs); + globpath(p_rtp, tail, gap, glob_flags, expand_dirs); } if (flags & DIP_START) { memcpy(tail - 15, "pack/*/start/*/", 15); // NOLINT - globpath(p_pp, tail - 15, &ga, glob_flags, expand_dirs); + globpath(p_pp, tail - 15, gap, glob_flags, expand_dirs); memcpy(tail - 8, "start/*/", 8); // NOLINT - globpath(p_pp, tail - 8, &ga, glob_flags, expand_dirs); + globpath(p_pp, tail - 8, gap, glob_flags, expand_dirs); } if (flags & DIP_OPT) { memcpy(tail - 13, "pack/*/opt/*/", 13); // NOLINT - globpath(p_pp, tail - 13, &ga, glob_flags, expand_dirs); + globpath(p_pp, tail - 13, gap, glob_flags, expand_dirs); memcpy(tail - 6, "opt/*/", 6); // NOLINT - globpath(p_pp, tail - 6, &ga, glob_flags, expand_dirs); + globpath(p_pp, tail - 6, gap, glob_flags, expand_dirs); } if (*dirnames[i] == NUL && !expand_dirs) { @@ -1278,13 +1258,12 @@ expand: } } - for (int i = 0; i < ga.ga_len; i++) { - char *match = ((char **)ga.ga_data)[i]; + for (int i = 0; i < gap->ga_len; i++) { + char *match = ((char **)gap->ga_data)[i]; char *s = match; char *e = s + strlen(s); - if (e - s > 4 && (flags & DIP_KEEPEXT) == 0 - && (STRNICMP(e - 4, ".vim", 4) == 0 - || STRNICMP(e - 4, ".lua", 4) == 0)) { + if (e - s > 4 && !keep_ext && (STRNICMP(e - 4, ".vim", 4) == 0 + || STRNICMP(e - 4, ".lua", 4) == 0)) { e -= 4; *e = NUL; } @@ -1296,26 +1275,82 @@ expand: } } s++; - *e = NUL; - assert((e - s) + 1 >= 0); - memmove(match, s, (size_t)(e - s) + 1); + if (s != match) { + assert((e - s) + 1 >= 0); + memmove(match, s, (size_t)(e - s) + 1); + } } - if (GA_EMPTY(&ga)) { - return FAIL; + if (GA_EMPTY(gap)) { + return; } // Sort and remove duplicates which can happen when specifying multiple // directories in dirnames. - ga_remove_duplicate_strings(&ga); + ga_remove_duplicate_strings(gap); +} + +/// Expand color scheme, compiler or filetype names. +/// Search from 'runtimepath': +/// 'runtimepath'/{dirnames}/{pat}.(vim|lua) +/// When "flags" has DIP_START: search also from "start" of 'packpath': +/// 'packpath'/pack/*/start/*/{dirnames}/{pat}.(vim|lua) +/// When "flags" has DIP_OPT: search also from "opt" of 'packpath': +/// 'packpath'/pack/*/opt/*/{dirnames}/{pat}.(vim|lua) +/// "dirnames" is an array with one or more directory names. +int ExpandRTDir(char *pat, int flags, int *num_file, char ***file, char *dirnames[]) +{ + *num_file = 0; + *file = NULL; + + garray_T ga; + ga_init(&ga, (int)sizeof(char *), 10); + + ExpandRTDir_int(pat, strlen(pat), flags, false, &ga, dirnames); + + if (GA_EMPTY(&ga)) { + return FAIL; + } *file = ga.ga_data; *num_file = ga.ga_len; return OK; } +/// Handle command line completion for :runtime command. +int expand_runtime_cmd(char *pat, int *numMatches, char ***matches) +{ + *numMatches = 0; + *matches = NULL; + + garray_T ga; + ga_init(&ga, sizeof(char *), 10); + + const size_t pat_len = strlen(pat); + char *dirnames[] = { "", NULL }; + ExpandRTDir_int(pat, pat_len, runtime_expand_flags, true, &ga, dirnames); + + // Try to complete values for [where] argument when none was found. + if (runtime_expand_flags == 0) { + char *where_values[] = { "START", "OPT", "PACK", "ALL" }; + for (size_t i = 0; i < ARRAY_SIZE(where_values); i++) { + if (strncmp(pat, where_values[i], pat_len) == 0) { + GA_APPEND(char *, &ga, xstrdup(where_values[i])); + } + } + } + + if (GA_EMPTY(&ga)) { + return FAIL; + } + + *matches = ga.ga_data; + *numMatches = ga.ga_len; + return OK; +} + /// Expand loadplugin names: -/// 'packpath'/pack/ * /opt/{pat} +/// 'packpath'/pack/*/opt/{pat} int ExpandPackAddDir(char *pat, int *num_file, char ***file) { garray_T ga; -- cgit From 27177e581902967dcf4f2f426464da1b636ca420 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sat, 11 Feb 2023 14:14:24 +0100 Subject: refactor: reduce scope of locals as per the style guide (#22211) --- src/nvim/runtime.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index b071e10cf9..70e1e00623 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -276,10 +276,8 @@ static void source_callback(char *fname, void *cookie) /// return FAIL when no file could be sourced, OK otherwise. int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, void *cookie) { - char *tail; int num_files; char **files; - int i; bool did_one = false; // Make a copy of 'runtimepath'. Invoking the callback may change the @@ -287,6 +285,8 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo char *rtp_copy = xstrdup(path); char *buf = xmallocz(MAXPATHL); { + char *tail; + int i; if (p_verbose > 10 && name != NULL) { verbose_enter(); smsg(_("Searching for \"%s\" in \"%s\""), name, path); @@ -2329,7 +2329,6 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat) { struct source_cookie *sp = (struct source_cookie *)cookie; char *line; - char *p; // If breakpoints have been added/deleted need to check for it. if (sp->dbg_tick < debug_tick) { @@ -2359,6 +2358,7 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat) // Only concatenate lines starting with a \ when 'cpoptions' doesn't // contain the 'C' flag. if (line != NULL && do_concat && (vim_strchr(p_cpo, CPO_CONCAT) == NULL)) { + char *p; // compensate for the one line read-ahead sp->sourcing_lnum--; -- cgit From 5f72ab77bff1f1224be5cbbf9423bdddbc25635c Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sun, 12 Feb 2023 18:48:49 +0100 Subject: refactor: reduce scope of locals as per the style guide 3 (#22221) refactor: reduce scope of locals as per the style guide --- src/nvim/runtime.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 70e1e00623..cff0f886ce 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -286,7 +286,6 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo char *buf = xmallocz(MAXPATHL); { char *tail; - int i; if (p_verbose > 10 && name != NULL) { verbose_enter(); smsg(_("Searching for \"%s\" in \"%s\""), name, path); @@ -335,7 +334,7 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo // Expand wildcards, invoke the callback for each match. if (gen_expand_wildcards(1, &buf, &num_files, &files, ew_flags) == OK) { - for (i = 0; i < num_files; i++) { + for (int i = 0; i < num_files; i++) { (*callback)(files[i], cookie); did_one = true; if (!(flags & DIP_ALL)) { @@ -416,7 +415,6 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c char *tail; int num_files; char **files; - int i; bool did_one = false; char buf[MAXPATHL]; @@ -469,7 +467,7 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c // Expand wildcards, invoke the callback for each match. char *(pat[]) = { buf }; if (gen_expand_wildcards(1, pat, &num_files, &files, ew_flags) == OK) { - for (i = 0; i < num_files; i++) { + for (int i = 0; i < num_files; i++) { (*callback)(files[i], cookie); did_one = true; if (!(flags & DIP_ALL)) { -- cgit From e619fb1660595f9e6a0afad8d9a91e37a94f95a3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 16 Feb 2023 10:32:28 +0800 Subject: vim-patch:8.2.0114: info about sourced scripts is scattered Problem: Info about sourced scripts is scattered. Solution: Use scriptitem_T for info about a script, including s: variables. Drop ga_scripts. https://github.com/vim/vim/commit/7ebcba61b20d25d23109fff73d0346ad44ba1b3b Co-authored-by: Bram Moolenaar --- src/nvim/runtime.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index cff0f886ce..e8b0492f35 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1846,10 +1846,13 @@ scriptitem_T *new_script_item(char *const name, scid_T *const sid_out) while (script_items.ga_len < sid) { script_items.ga_len++; SCRIPT_ITEM(script_items.ga_len).sn_name = NULL; + + // Allocate the local script variables to use for this script. + new_script_vars(script_items.ga_len); + SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false; } SCRIPT_ITEM(sid).sn_name = name; - new_script_vars(sid); // Allocate the local script variables to use for this script. return &SCRIPT_ITEM(sid); } @@ -2305,7 +2308,14 @@ void free_scriptnames(void) { profile_reset(); -# define FREE_SCRIPTNAME(item) xfree((item)->sn_name) +# define FREE_SCRIPTNAME(item) \ + do { \ + /* the variables themselves are cleared in evalvars_clear() */ \ + xfree((item)->sn_vars); \ + xfree((item)->sn_name); \ + ga_clear(&(item)->sn_prl_ga); \ + } while (0) \ + GA_DEEP_CLEAR(&script_items, scriptitem_T, FREE_SCRIPTNAME); } #endif -- cgit From 0cbbe27e93e87a5336673e0529b011313c51a123 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 16 Feb 2023 11:00:48 +0800 Subject: vim-patch:8.2.0154: reallocating the list of scripts is inefficient Problem: Reallocating the list of scripts is inefficient. Solution: Instead of using a growarray of scriptitem_T, store pointers and allocate each scriptitem_T separately. Also avoids that the growarray pointers change when sourcing a new script. https://github.com/vim/vim/commit/21b9e9773d64de40994f8762173bdd8befa6acf7 Co-authored-by: Bram Moolenaar --- src/nvim/runtime.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index e8b0492f35..9dc213d718 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -73,7 +73,7 @@ struct source_cookie { #endif garray_T exestack = { 0, 0, sizeof(estack_T), 50, NULL }; -garray_T script_items = { 0, 0, sizeof(scriptitem_T), 4, NULL }; +garray_T script_items = { 0, 0, sizeof(scriptitem_T *), 20, NULL }; /// Initialize the execution stack. void estack_init(void) @@ -144,7 +144,7 @@ char *estack_sfile(estack_arg_T which) ? &entry->es_info.ufunc->uf_script_ctx : &entry->es_info.aucmd->script_ctx); return def_ctx->sc_sid > 0 - ? xstrdup((SCRIPT_ITEM(def_ctx->sc_sid).sn_name)) + ? xstrdup((SCRIPT_ITEM(def_ctx->sc_sid)->sn_name)) : NULL; } else if (entry->es_type == ETYPE_SCRIPT) { return xstrdup(entry->es_name); @@ -1844,16 +1844,18 @@ scriptitem_T *new_script_item(char *const name, scid_T *const sid_out) } ga_grow(&script_items, sid - script_items.ga_len); while (script_items.ga_len < sid) { + scriptitem_T *si = xcalloc(1, sizeof(scriptitem_T)); script_items.ga_len++; - SCRIPT_ITEM(script_items.ga_len).sn_name = NULL; + SCRIPT_ITEM(script_items.ga_len) = si; + si->sn_name = NULL; // Allocate the local script variables to use for this script. new_script_vars(script_items.ga_len); - SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false; + si->sn_prof_on = false; } - SCRIPT_ITEM(sid).sn_name = name; - return &SCRIPT_ITEM(sid); + SCRIPT_ITEM(sid)->sn_name = name; + return SCRIPT_ITEM(sid); } static int source_using_linegetter(void *cookie, LineGetter fgetline, const char *traceback_name) @@ -2121,7 +2123,7 @@ int do_source(char *fname, int check_other, int is_vimrc) if (l_do_profiling == PROF_YES) { // Get "si" again, "script_items" may have been reallocated. - si = &SCRIPT_ITEM(current_sctx.sc_sid); + si = SCRIPT_ITEM(current_sctx.sc_sid); if (si->sn_prof_on) { si->sn_pr_start = profile_end(si->sn_pr_start); si->sn_pr_start = profile_sub_wait(wait_start, si->sn_pr_start); @@ -2201,7 +2203,7 @@ scriptitem_T *get_current_script_id(char **fnamep, sctx_T *ret_sctx) // inode number, even though to the user it is the same script. // - If a script is deleted and another script is written, with a // different name, the inode may be re-used. - si = &SCRIPT_ITEM(script_sctx.sc_sid); + si = SCRIPT_ITEM(script_sctx.sc_sid); if (si->sn_name != NULL && path_fnamecmp(si->sn_name, *fnamep) == 0) { // Found it! break; @@ -2227,7 +2229,7 @@ void ex_scriptnames(exarg_T *eap) emsg(_(e_invarg)); } else { if (eap->addr_count > 0) { - eap->arg = SCRIPT_ITEM(eap->line2).sn_name; + eap->arg = SCRIPT_ITEM(eap->line2)->sn_name; } else { expand_env(eap->arg, NameBuff, MAXPATHL); eap->arg = NameBuff; @@ -2238,8 +2240,8 @@ void ex_scriptnames(exarg_T *eap) } for (int i = 1; i <= script_items.ga_len && !got_int; i++) { - if (SCRIPT_ITEM(i).sn_name != NULL) { - home_replace(NULL, SCRIPT_ITEM(i).sn_name, NameBuff, MAXPATHL, true); + if (SCRIPT_ITEM(i)->sn_name != NULL) { + home_replace(NULL, SCRIPT_ITEM(i)->sn_name, NameBuff, MAXPATHL, true); vim_snprintf(IObuff, IOSIZE, "%3d: %s", i, NameBuff); if (!message_filtered(IObuff)) { msg_putchar('\n'); @@ -2255,8 +2257,8 @@ void ex_scriptnames(exarg_T *eap) void scriptnames_slash_adjust(void) { for (int i = 1; i <= script_items.ga_len; i++) { - if (SCRIPT_ITEM(i).sn_name != NULL) { - slash_adjust(SCRIPT_ITEM(i).sn_name); + if (SCRIPT_ITEM(i)->sn_name != NULL) { + slash_adjust(SCRIPT_ITEM(i)->sn_name); } } } @@ -2290,7 +2292,7 @@ char *get_scriptname(LastSet last_set, bool *should_free) case SID_STR: return _("anonymous :source"); default: { - char *const sname = SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name; + char *const sname = SCRIPT_ITEM(last_set.script_ctx.sc_sid)->sn_name; if (sname == NULL) { snprintf(IObuff, IOSIZE, _("anonymous :source (script id %d)"), last_set.script_ctx.sc_sid); @@ -2310,13 +2312,15 @@ void free_scriptnames(void) # define FREE_SCRIPTNAME(item) \ do { \ + scriptitem_T *_si = *(item); \ /* the variables themselves are cleared in evalvars_clear() */ \ - xfree((item)->sn_vars); \ - xfree((item)->sn_name); \ - ga_clear(&(item)->sn_prl_ga); \ + xfree(_si->sn_vars); \ + xfree(_si->sn_name); \ + ga_clear(&_si->sn_prl_ga); \ + xfree(_si); \ } while (0) \ - GA_DEEP_CLEAR(&script_items, scriptitem_T, FREE_SCRIPTNAME); + GA_DEEP_CLEAR(&script_items, scriptitem_T *, FREE_SCRIPTNAME); } #endif -- cgit From d34c64e342dfba9248d1055e702d02620a1b31a8 Mon Sep 17 00:00:00 2001 From: Ghjuvan Lacambre Date: Thu, 16 Feb 2023 13:15:02 +0100 Subject: feat: $NVIM_APPNAME #22128 This commit implements the ability to control all of the XDG paths Neovim should use. This is done by setting an environment variable named NVIM_APPNAME. For example, setting $NVIM_APPNAME makes Neovim look for its configuration directory in $XDG_CONFIG_HOME/$NVIM_APPNAME instead of $XDG_CONFIG_HOME/nvim. If NVIM_APPNAME is not set or is an empty string, "nvim" will be used as default. The usecase for this feature is to enable an easy way to switch from configuration to configuration. One might argue that the various $XDG environment variables can already be used for this usecase. However, setting $XDG environment variables also affects tools spawned by Neovim. For example, while setting $XDG_CONFIG_HOME will enable Neovim to use a different configuration directory, it will also prevent Git from finding its "default" configuration. Closes https://github.com/neovim/neovim/issues/21691 --- src/nvim/runtime.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 9dc213d718..3487a8d7a2 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1435,7 +1435,6 @@ static inline size_t compute_double_env_sep_len(const char *const val, const siz return ret; } -#define NVIM_SIZE (sizeof("nvim") - 1) /// Add directories to a ENV_SEPCHAR-separated array from a colon-separated one /// /// Commas are escaped in process. To each item PATHSEP "nvim" is appended in @@ -1464,6 +1463,8 @@ static inline char *add_env_sep_dirs(char *dest, const char *const val, const ch return dest; } const void *iter = NULL; + const char *appname = get_appname(); + const size_t appname_len = strlen(appname); do { size_t dir_len; const char *dir; @@ -1474,8 +1475,8 @@ static inline char *add_env_sep_dirs(char *dest, const char *const val, const ch if (!after_pathsep(dest - 1, dest)) { *dest++ = PATHSEP; } - memmove(dest, "nvim", NVIM_SIZE); - dest += NVIM_SIZE; + memmove(dest, appname, appname_len); + dest += appname_len; if (suf1 != NULL) { *dest++ = PATHSEP; memmove(dest, suf1, len1); @@ -1529,14 +1530,18 @@ static inline char *add_dir(char *dest, const char *const dir, const size_t dir_ if (!after_pathsep(dest - 1, dest)) { *dest++ = PATHSEP; } + const char *appname = get_appname(); + size_t appname_len = strlen(appname); + assert(appname_len < (IOSIZE - sizeof("-data"))); + xstrlcpy(IObuff, appname, appname_len + 1); #if defined(MSWIN) - size_t size = (type == kXDGDataHome ? sizeof("nvim-data") - 1 : NVIM_SIZE); - memmove(dest, (type == kXDGDataHome ? "nvim-data" : "nvim"), size); - dest += size; -#else - memmove(dest, "nvim", NVIM_SIZE); - dest += NVIM_SIZE; + if (type == kXDGDataHome || type == kXDGStateHome) { + STRCAT(IObuff, "-data"); + appname_len += 5; + } #endif + xstrlcpy(dest, IObuff, appname_len + 1); + dest += appname_len; if (suf1 != NULL) { *dest++ = PATHSEP; memmove(dest, suf1, len1); @@ -1596,16 +1601,17 @@ char *runtimepath_default(bool clean_arg) size_t config_len = 0; size_t vimruntime_len = 0; size_t libdir_len = 0; + const char *appname = get_appname(); + size_t appname_len = strlen(appname); if (data_home != NULL) { data_len = strlen(data_home); - if (data_len != 0) { + size_t nvim_data_size = appname_len; #if defined(MSWIN) - size_t nvim_size = (sizeof("nvim-data") - 1); -#else - size_t nvim_size = NVIM_SIZE; + nvim_data_size += sizeof("-data"); #endif + if (data_len != 0) { rtp_size += ((data_len + memcnt(data_home, ',', data_len) - + nvim_size + 1 + SITE_SIZE + 1 + + nvim_data_size + 1 + SITE_SIZE + 1 + !after_pathsep(data_home, data_home + data_len)) * 2 + AFTER_SIZE + 1); } @@ -1614,7 +1620,7 @@ char *runtimepath_default(bool clean_arg) config_len = strlen(config_home); if (config_len != 0) { rtp_size += ((config_len + memcnt(config_home, ',', config_len) - + NVIM_SIZE + 1 + + appname_len + 1 + !after_pathsep(config_home, config_home + config_len)) * 2 + AFTER_SIZE + 1); } @@ -1632,9 +1638,9 @@ char *runtimepath_default(bool clean_arg) } } rtp_size += compute_double_env_sep_len(data_dirs, - NVIM_SIZE + 1 + SITE_SIZE + 1, + appname_len + 1 + SITE_SIZE + 1, AFTER_SIZE + 1); - rtp_size += compute_double_env_sep_len(config_dirs, NVIM_SIZE + 1, + rtp_size += compute_double_env_sep_len(config_dirs, appname_len + 1, AFTER_SIZE + 1); char *rtp = NULL; if (rtp_size == 0) { @@ -1675,7 +1681,6 @@ freeall: return rtp; } -#undef NVIM_SIZE static void cmd_source(char *fname, exarg_T *eap) { -- cgit From c726585ce1a5a8776e747fe20bead0acec88edf4 Mon Sep 17 00:00:00 2001 From: Ghjuvan Lacambre Date: Sun, 19 Feb 2023 13:25:29 +0100 Subject: fix: windows assertion failure due to incorrect path length (#22324) This commit fixes an assertion failure on windows debug builds that was introduced in https://github.com/neovim/neovim/pull/22128 . --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 3487a8d7a2..a6ed95ec64 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1607,7 +1607,7 @@ char *runtimepath_default(bool clean_arg) data_len = strlen(data_home); size_t nvim_data_size = appname_len; #if defined(MSWIN) - nvim_data_size += sizeof("-data"); + nvim_data_size += sizeof("-data") - 1; // -1: NULL byte should be ignored #endif if (data_len != 0) { rtp_size += ((data_len + memcnt(data_home, ',', data_len) -- cgit From 674e23f19c509381e2476a3990e21272e362e3a4 Mon Sep 17 00:00:00 2001 From: Michal Liszcz Date: Sat, 11 Mar 2023 04:22:22 +0100 Subject: vim-patch:9.0.0244: cannot easily get the list of sourced scripts (#22596) Problem: Cannot easily get the list of sourced scripts. Solution: Add the getscriptinfo() function. (Yegappan Lakshmanan, closes vim/vim#10957) https://github.com/vim/vim/commit/f768c3d19c518822d89dec4cc3947ddeea249316 Cherry-pick usr_41.txt change from a later runtime update. Co-authored-by: Yegappan Lakshmanan --- src/nvim/runtime.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index a6ed95ec64..7a3efc5760 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2337,6 +2337,29 @@ linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie) : SOURCING_LNUM; } +/// "getscriptinfo()" function +void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + tv_list_alloc_ret(rettv, script_items.ga_len); + + list_T *l = rettv->vval.v_list; + + for (int i = 1; i <= script_items.ga_len; i++) { + scriptitem_T *si = SCRIPT_ITEM(i); + + if (si->sn_name == NULL) { + continue; + } + + dict_T *d = tv_dict_alloc(); + tv_list_append_dict(l, d); + tv_dict_add_str(d, S_LEN("name"), si->sn_name); + tv_dict_add_nr(d, S_LEN("sid"), i); + // Vim9 autoload script (:h vim9-autoload), not applicable to Nvim. + tv_dict_add_bool(d, S_LEN("autoload"), false); + } +} + /// Get one full line from a sourced file. /// Called by do_cmdline() when it's called from do_source(). /// -- cgit From a7cd79349c97f623955f4a5cf84921ca8ab9ea42 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 11 Mar 2023 12:47:27 +0800 Subject: refactor(runtime.c): factor out find_script_by_name() (#22620) This the refactoring done in Vim patch 8.2.4050. --- src/nvim/runtime.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 7a3efc5760..3326f4e096 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2187,6 +2187,25 @@ theend: return retval; } +/// Find an already loaded script "name". +/// If found returns its script ID. If not found returns -1. +static int find_script_by_name(char *name) +{ + assert(script_items.ga_len >= 0); + for (int sid = script_items.ga_len; sid > 0; sid--) { + // We used to check inode here, but that doesn't work: + // - If a script is edited and written, it may get a different + // inode number, even though to the user it is the same script. + // - If a script is deleted and another script is written, with a + // different name, the inode may be re-used. + scriptitem_T *si = SCRIPT_ITEM(sid); + if (si->sn_name != NULL && path_fnamecmp(si->sn_name, name) == 0) { + return sid; + } + } + return -1; +} + /// Check if fname was sourced before to finds its SID. /// If it's new, generate a new SID. /// @@ -2196,28 +2215,19 @@ scriptitem_T *get_current_script_id(char **fnamep, sctx_T *ret_sctx) { static int last_current_SID_seq = 0; + scriptitem_T *si; + int sid = find_script_by_name(*fnamep); + if (sid > 0) { + si = SCRIPT_ITEM(sid); + } else { + si = new_script_item(*fnamep, &sid); + *fnamep = xstrdup(si->sn_name); + } + sctx_T script_sctx = { .sc_seq = ++last_current_SID_seq, .sc_lnum = 0, - .sc_sid = 0 }; - scriptitem_T *si = NULL; + .sc_sid = sid }; - assert(script_items.ga_len >= 0); - for (script_sctx.sc_sid = script_items.ga_len; script_sctx.sc_sid > 0; script_sctx.sc_sid--) { - // We used to check inode here, but that doesn't work: - // - If a script is edited and written, it may get a different - // inode number, even though to the user it is the same script. - // - If a script is deleted and another script is written, with a - // different name, the inode may be re-used. - si = SCRIPT_ITEM(script_sctx.sc_sid); - if (si->sn_name != NULL && path_fnamecmp(si->sn_name, *fnamep) == 0) { - // Found it! - break; - } - } - if (script_sctx.sc_sid == 0) { - si = new_script_item(*fnamep, &script_sctx.sc_sid); - *fnamep = xstrdup(si->sn_name); - } if (ret_sctx != NULL) { *ret_sctx = script_sctx; } -- cgit From 402c31a82d2961172c6eaf8014762f28c60bd93e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 11 Mar 2023 17:58:05 +0800 Subject: refactor: move ga_loaded to runtime.c (#22626) --- src/nvim/runtime.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 3326f4e096..c316b61082 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -75,6 +75,9 @@ struct source_cookie { garray_T exestack = { 0, 0, sizeof(estack_T), 50, NULL }; garray_T script_items = { 0, 0, sizeof(scriptitem_T *), 20, NULL }; +/// The names of packages that once were loaded are remembered. +static garray_T ga_loaded = { 0, 0, sizeof(char *), 4, NULL }; + /// Initialize the execution stack. void estack_init(void) { @@ -2339,6 +2342,11 @@ void free_scriptnames(void) } #endif +void free_autoload_scriptnames(void) +{ + ga_clear_strings(&ga_loaded); +} + linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie) FUNC_ATTR_PURE { @@ -2630,3 +2638,77 @@ bool source_finished(LineGetter fgetline, void *cookie) return getline_equal(fgetline, cookie, getsourceline) && ((struct source_cookie *)getline_cookie(fgetline, cookie))->finished; } + +/// Return the autoload script name for a function or variable name +/// Caller must make sure that "name" contains AUTOLOAD_CHAR. +/// +/// @param[in] name Variable/function name. +/// @param[in] name_len Name length. +/// +/// @return [allocated] autoload script name. +char *autoload_name(const char *const name, const size_t name_len) + FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT +{ + // Get the script file name: replace '#' with '/', append ".vim". + char *const scriptname = xmalloc(name_len + sizeof("autoload/.vim")); + memcpy(scriptname, "autoload/", sizeof("autoload/") - 1); + memcpy(scriptname + sizeof("autoload/") - 1, name, name_len); + size_t auchar_idx = 0; + for (size_t i = sizeof("autoload/") - 1; + i - sizeof("autoload/") + 1 < name_len; + i++) { + if (scriptname[i] == AUTOLOAD_CHAR) { + scriptname[i] = '/'; + auchar_idx = i; + } + } + memcpy(scriptname + auchar_idx, ".vim", sizeof(".vim")); + + return scriptname; +} + +/// If name has a package name try autoloading the script for it +/// +/// @param[in] name Variable/function name. +/// @param[in] name_len Name length. +/// @param[in] reload If true, load script again when already loaded. +/// +/// @return true if a package was loaded. +bool script_autoload(const char *const name, const size_t name_len, const bool reload) +{ + // If there is no '#' after name[0] there is no package name. + const char *p = memchr(name, AUTOLOAD_CHAR, name_len); + if (p == NULL || p == name) { + return false; + } + + bool ret = false; + char *tofree = autoload_name(name, name_len); + char *scriptname = tofree; + + // Find the name in the list of previously loaded package names. Skip + // "autoload/", it's always the same. + int i = 0; + for (; i < ga_loaded.ga_len; i++) { + if (strcmp(((char **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) { + break; + } + } + if (!reload && i < ga_loaded.ga_len) { + ret = false; // Was loaded already. + } else { + // Remember the name if it wasn't loaded already. + if (i == ga_loaded.ga_len) { + GA_APPEND(char *, &ga_loaded, scriptname); + tofree = NULL; + } + + // Try loading the package from $VIMRUNTIME/autoload/.vim + if (source_runtime(scriptname, 0) == OK) { + ret = true; + } + } + + xfree(tofree); + return ret; +} -- cgit From 7dc9182cf0b27cbfb4e289db55dd7b02998ef5c8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 11 Mar 2023 21:29:25 +0800 Subject: vim-patch:8.2.1398: autoload script sourced twice if sourced directly (#22622) Problem: Autoload script sourced twice if sourced directly. Solution: Do not source an autoload script again. (issue vim/vim#6644) https://github.com/vim/vim/commit/daa2f36573db3e1df7eb1fdbc3a09a2815644048 Cherry-pick ret_sid changes from patch 8.2.0149. Use do_in_runtimepath() as that's what source_runtime() calls in Nvim. Co-authored-by: Bram Moolenaar --- src/nvim/runtime.c | 76 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 36 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index c316b61082..c9667d58ed 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -78,6 +78,8 @@ garray_T script_items = { 0, 0, sizeof(scriptitem_T *), 20, NULL }; /// The names of packages that once were loaded are remembered. static garray_T ga_loaded = { 0, 0, sizeof(char *), 4, NULL }; +static int last_current_SID_seq = 0; + /// Initialize the execution stack. void estack_init(void) { @@ -266,7 +268,7 @@ void set_context_in_runtime_cmd(expand_T *xp, const char *arg) static void source_callback(char *fname, void *cookie) { - (void)do_source(fname, false, DOSO_NONE); + (void)do_source(fname, false, DOSO_NONE, cookie); } /// Find the file "name" in all directories in "path" and invoke @@ -855,7 +857,7 @@ static void source_all_matches(char *pat) } for (int i = 0; i < num_files; i++) { - (void)do_source(files[i], false, DOSO_NONE); + (void)do_source(files[i], false, DOSO_NONE, NULL); } FreeWild(num_files, files); } @@ -1701,7 +1703,7 @@ static void cmd_source(char *fname, exarg_T *eap) || eap->cstack->cs_idx >= 0); // ":source" read ex commands - } else if (do_source(fname, false, DOSO_NONE) == FAIL) { + } else if (do_source(fname, false, DOSO_NONE, NULL) == FAIL) { semsg(_(e_notopen), fname); } } @@ -1954,9 +1956,12 @@ int do_source_str(const char *cmd, const char *traceback_name) /// @param fname /// @param check_other check for .vimrc and _vimrc /// @param is_vimrc DOSO_ value +/// @param ret_sid if not NULL and we loaded the script before, don't load it again /// /// @return FAIL if file could not be opened, OK otherwise -int do_source(char *fname, int check_other, int is_vimrc) +/// +/// If a scriptitem_T was found or created "*ret_sid" is set to the SID. +int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) { struct source_cookie cookie; char *p; @@ -1982,6 +1987,15 @@ int do_source(char *fname, int check_other, int is_vimrc) goto theend; } + // See if we loaded this script before. + int sid = find_script_by_name(fname_exp); + if (sid > 0 && ret_sid != NULL) { + // Already loaded and no need to load again, return here. + *ret_sid = sid; + retval = OK; + goto theend; + } + // Apply SourceCmd autocommands, they should get the file and source it. if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL) && apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp, @@ -2080,7 +2094,24 @@ int do_source(char *fname, int check_other, int is_vimrc) save_funccal(&funccalp_entry); const sctx_T save_current_sctx = current_sctx; - si = get_current_script_id(&fname_exp, ¤t_sctx); + + current_sctx.sc_lnum = 0; + + // Always use a new sequence number. + current_sctx.sc_seq = ++last_current_SID_seq; + + if (sid > 0) { + // loading the same script again + si = SCRIPT_ITEM(sid); + } else { + // It's new, generate a new SID. + si = new_script_item(fname_exp, &sid); + fname_exp = xstrdup(si->sn_name); // used for autocmd + if (ret_sid != NULL) { + *ret_sid = sid; + } + } + current_sctx.sc_sid = sid; // Keep the sourcing name/lnum, for recursive calls. estack_push(ETYPE_SCRIPT, si->sn_name, 0); @@ -2192,7 +2223,7 @@ theend: /// Find an already loaded script "name". /// If found returns its script ID. If not found returns -1. -static int find_script_by_name(char *name) +int find_script_by_name(char *name) { assert(script_items.ga_len >= 0); for (int sid = script_items.ga_len; sid > 0; sid--) { @@ -2209,35 +2240,6 @@ static int find_script_by_name(char *name) return -1; } -/// Check if fname was sourced before to finds its SID. -/// If it's new, generate a new SID. -/// -/// @param[in,out] fnamep pointer to file path of script -/// @param[out] ret_sctx sctx of this script -scriptitem_T *get_current_script_id(char **fnamep, sctx_T *ret_sctx) -{ - static int last_current_SID_seq = 0; - - scriptitem_T *si; - int sid = find_script_by_name(*fnamep); - if (sid > 0) { - si = SCRIPT_ITEM(sid); - } else { - si = new_script_item(*fnamep, &sid); - *fnamep = xstrdup(si->sn_name); - } - - sctx_T script_sctx = { .sc_seq = ++last_current_SID_seq, - .sc_lnum = 0, - .sc_sid = sid }; - - if (ret_sctx != NULL) { - *ret_sctx = script_sctx; - } - - return si; -} - /// ":scriptnames" void ex_scriptnames(exarg_T *eap) { @@ -2704,7 +2706,9 @@ bool script_autoload(const char *const name, const size_t name_len, const bool r } // Try loading the package from $VIMRUNTIME/autoload/.vim - if (source_runtime(scriptname, 0) == OK) { + // Use "ret_sid" to avoid loading the same script again. + int ret_sid; + if (do_in_runtimepath(scriptname, 0, source_callback, &ret_sid) == OK) { ret = true; } } -- cgit From 4f66530af1d5e501f7b57ddd79e9c185af1b5f39 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 1 Apr 2023 21:34:55 +0800 Subject: vim-patch:9.0.1434: crash when adding package already in 'runtimepath' (#22849) Problem: Crash when adding package already in 'runtimepath'. Solution: Change order for using 'runtimepath' entries. (closes vim/vim#12215) https://github.com/vim/vim/commit/39c9ec16ea7ef13c5d783481542ee9aa6c05282c --- src/nvim/runtime.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index c9667d58ed..5d1c104dc5 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -914,19 +914,6 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) const char *cur_entry = entry; copy_option_part((char **)&entry, buf, MAXPATHL, ","); - if (insp == NULL) { - add_pathsep(buf); - char *const rtp_ffname = fix_fname(buf); - if (rtp_ffname == NULL) { - goto theend; - } - bool match = path_fnamencmp(rtp_ffname, ffname, fname_len) == 0; - xfree(rtp_ffname); - if (match) { - // Insert "ffname" after this entry (and comma). - insp = entry; - } - } if ((p = strstr(buf, "after")) != NULL && p > buf @@ -940,6 +927,20 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) after_insp = cur_entry; break; } + + if (insp == NULL) { + add_pathsep(buf); + char *const rtp_ffname = fix_fname(buf); + if (rtp_ffname == NULL) { + goto theend; + } + bool match = path_fnamencmp(rtp_ffname, ffname, fname_len) == 0; + xfree(rtp_ffname); + if (match) { + // Insert "ffname" after this entry (and comma). + insp = entry; + } + } } if (insp == NULL) { -- cgit From 9408f2dcf7cade2631688300e9b58eed6bc5219a Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Fri, 7 Apr 2023 19:40:57 +0200 Subject: refactor: remove redundant const char * casts --- src/nvim/runtime.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 5d1c104dc5..c02e12ae61 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -910,7 +910,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) } const char *insp = NULL; const char *after_insp = NULL; - for (const char *entry = (const char *)p_rtp; *entry != NUL;) { + for (const char *entry = p_rtp; *entry != NUL;) { const char *cur_entry = entry; copy_option_part((char **)&entry, buf, MAXPATHL, ","); @@ -945,7 +945,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) if (insp == NULL) { // Both "fname" and "after" not found, append at the end. - insp = (const char *)p_rtp + strlen(p_rtp); + insp = p_rtp + strlen(p_rtp); } // check if rtp/pack/name/start/name/after exists @@ -966,7 +966,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) // We now have 'rtp' parts: {keep}{keep_after}{rest}. // Create new_rtp, first: {keep},{fname} - size_t keep = (size_t)(insp - (const char *)p_rtp); + size_t keep = (size_t)(insp - p_rtp); memmove(new_rtp, p_rtp, keep); size_t new_rtp_len = keep; if (*insp == NUL) { @@ -979,7 +979,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) } if (afterlen > 0 && after_insp != NULL) { - size_t keep_after = (size_t)(after_insp - (const char *)p_rtp); + size_t keep_after = (size_t)(after_insp - p_rtp); // Add to new_rtp: {keep},{fname}{keep_after},{afterdir} memmove(new_rtp + new_rtp_len, p_rtp + keep, keep_after - keep); @@ -1061,7 +1061,7 @@ static void add_pack_plugin(bool opt, char *fname, void *cookie) char *buf = xmalloc(MAXPATHL); bool found = false; - const char *p = (const char *)p_rtp; + const char *p = p_rtp; while (*p != NUL) { copy_option_part((char **)&p, buf, MAXPATHL, ","); if (path_fnamecmp(buf, fname) == 0) { @@ -1925,12 +1925,10 @@ static void cmd_source_buffer(const exarg_T *const eap) .offset = 0, }; if (curbuf->b_fname - && path_with_extension((const char *)curbuf->b_fname, "lua")) { - nlua_source_using_linegetter(get_str_line, (void *)&cookie, - ":source (no file)"); + && path_with_extension(curbuf->b_fname, "lua")) { + nlua_source_using_linegetter(get_str_line, (void *)&cookie, ":source (no file)"); } else { - source_using_linegetter((void *)&cookie, get_str_line, - ":source (no file)"); + source_using_linegetter((void *)&cookie, get_str_line, ":source (no file)"); } ga_clear(&ga); } @@ -2134,12 +2132,12 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) cookie.conv.vc_type = CONV_NONE; // no conversion - if (path_with_extension((const char *)fname_exp, "lua")) { + if (path_with_extension(fname_exp, "lua")) { const sctx_T current_sctx_backup = current_sctx; current_sctx.sc_sid = SID_LUA; current_sctx.sc_lnum = 0; // Source the file as lua - nlua_exec_file((const char *)fname_exp); + nlua_exec_file(fname_exp); current_sctx = current_sctx_backup; } else { // Read the first line so we can check for a UTF-8 BOM. -- cgit From 04933b1ea968f958d2541dd65fd33ebb503caac3 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Fri, 7 Apr 2023 21:08:16 +0200 Subject: refactor: remove redundant casts --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index c02e12ae61..8d69e786c7 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1832,7 +1832,7 @@ static char *get_str_line(int c, void *cookie, int indent, bool do_concat) if (!concat_continued_line(&ga, 400, line, (size_t)(next_eol - line))) { break; } - eol = (char *)next_eol; + eol = next_eol; } } ga_append(&ga, NUL); -- cgit From 2d78e656b715119ca11d131a1a932f22f1b4ad36 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Fri, 7 Apr 2023 21:43:00 +0200 Subject: refactor: remove redundant casts --- src/nvim/runtime.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 8d69e786c7..1e39b58543 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1039,7 +1039,7 @@ static int load_pack_plugin(bool opt, char *fname) do_cmdline_cmd("augroup filetypedetect"); vim_snprintf(pat, len, ftpat, ffname); source_all_matches(pat); - vim_snprintf((char *)pat, len, "%s/ftdetect/*.lua", ffname); // NOLINT + vim_snprintf(pat, len, "%s/ftdetect/*.lua", ffname); // NOLINT source_all_matches(pat); do_cmdline_cmd("augroup END"); } @@ -1784,7 +1784,7 @@ static bool concat_continued_line(garray_T *const ga, const int init_growsize, c size_t len) FUNC_ATTR_NONNULL_ALL { - const char *const line = skipwhite_len((char *)p, len); + const char *const line = skipwhite_len(p, len); len -= (size_t)(line - p); // Skip lines starting with '\" ', concat lines starting with '\' if (len >= 3 && strncmp(line, "\"\\ ", 3) == 0) { @@ -1878,7 +1878,7 @@ static int source_using_linegetter(void *cookie, LineGetter fgetline, const char if (save_sourcing_name == NULL) { sname = (char *)traceback_name; } else { - snprintf((char *)sourcing_name_buf, sizeof(sourcing_name_buf), + snprintf(sourcing_name_buf, sizeof(sourcing_name_buf), "%s called at %s:%" PRIdLINENR, traceback_name, save_sourcing_name, save_sourcing_lnum); sname = sourcing_name_buf; -- cgit From bcc971de15ed540356405f937d640eaffa4a03bb Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 15 Apr 2023 19:50:23 +0800 Subject: vim-patch:9.0.0269: getscriptinfo() does not include the version Problem: getscriptinfo() does not include the version. Cannot select entries by script name. Solution: Add the "version" item and the "name" argument. (Yegappan Lakshmanan, closes vim/vim#10962) https://github.com/vim/vim/commit/520f6ef60a59f7b5f3da9199999d13dbe817d3ce Co-authored-by: Yegappan Lakshmanan --- src/nvim/runtime.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 1e39b58543..5bc63453c9 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -43,6 +43,7 @@ #include "nvim/os/stdpaths_defs.h" #include "nvim/path.h" #include "nvim/profile.h" +#include "nvim/regexp.h" #include "nvim/runtime.h" #include "nvim/strings.h" #include "nvim/usercmd.h" @@ -2361,8 +2362,25 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { tv_list_alloc_ret(rettv, script_items.ga_len); + if (tv_check_for_opt_dict_arg(argvars, 0) == FAIL) { + return; + } + list_T *l = rettv->vval.v_list; + regmatch_T regmatch = { + .regprog = NULL, + .rm_ic = p_ic, + }; + + char *pat = NULL; + if (argvars[0].v_type == VAR_DICT) { + pat = tv_dict_get_string(argvars[0].vval.v_dict, "name", true); + if (pat != NULL) { + regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); + } + } + for (int i = 1; i <= script_items.ga_len; i++) { scriptitem_T *si = SCRIPT_ITEM(i); @@ -2370,13 +2388,22 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) continue; } + if (pat != NULL && regmatch.regprog != NULL + && !vim_regexec(®match, si->sn_name, (colnr_T)0)) { + continue; + } + dict_T *d = tv_dict_alloc(); tv_list_append_dict(l, d); tv_dict_add_str(d, S_LEN("name"), si->sn_name); tv_dict_add_nr(d, S_LEN("sid"), i); + tv_dict_add_nr(d, S_LEN("version"), 1); // Vim9 autoload script (:h vim9-autoload), not applicable to Nvim. tv_dict_add_bool(d, S_LEN("autoload"), false); } + + vim_regfree(regmatch.regprog); + xfree(pat); } /// Get one full line from a sourced file. -- cgit From e9b4f5105100ce2279915bbe1d67d299c294db24 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 15 Apr 2023 19:57:55 +0800 Subject: vim-patch:9.0.0303: it is not easy to get information about a script Problem: It is not easy to get information about a script. Solution: Make getscriptinf() return the version. When selecting a specific script return functions and variables. (Yegappan Lakshmanan, closes vim/vim#10991) https://github.com/vim/vim/commit/2f892d8663498c21296ad6661dac1bb8372cfd10 Co-authored-by: Yegappan Lakshmanan --- src/nvim/runtime.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 5bc63453c9..a659dba575 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -22,6 +22,7 @@ #include "nvim/cmdexpand.h" #include "nvim/debugger.h" #include "nvim/eval.h" +#include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" @@ -2357,6 +2358,26 @@ linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie) : SOURCING_LNUM; } +/// Return a List of script-local functions defined in the script with id "sid". +static list_T *get_script_local_funcs(scid_T sid) +{ + hashtab_T *const functbl = func_tbl_get(); + list_T *l = tv_list_alloc((ptrdiff_t)functbl->ht_used); + + // Iterate through all the functions in the global function hash table + // looking for functions with script ID "sid". + HASHTAB_ITER(functbl, hi, { + const ufunc_T *const fp = HI2UF(hi); + // Add active functions with script id == "sid" + if (!(fp->uf_flags & FC_DEAD) && (fp->uf_script_ctx.sc_sid == sid)) { + const char *const name = fp->uf_name_exp != NULL ? fp->uf_name_exp : fp->uf_name; + tv_list_append_string(l, name, -1); + } + }); + + return l; +} + /// "getscriptinfo()" function void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { @@ -2372,12 +2393,20 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) .regprog = NULL, .rm_ic = p_ic, }; + bool filterpat = false; + varnumber_T sid = -1; char *pat = NULL; if (argvars[0].v_type == VAR_DICT) { - pat = tv_dict_get_string(argvars[0].vval.v_dict, "name", true); - if (pat != NULL) { - regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); + sid = tv_dict_get_number_def(argvars[0].vval.v_dict, "sid", -1); + if (sid == -1) { + pat = tv_dict_get_string(argvars[0].vval.v_dict, "name", true); + if (pat != NULL) { + regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); + } + if (regmatch.regprog != NULL) { + filterpat = true; + } } } @@ -2388,8 +2417,11 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) continue; } - if (pat != NULL && regmatch.regprog != NULL - && !vim_regexec(®match, si->sn_name, (colnr_T)0)) { + if (filterpat && !vim_regexec(®match, si->sn_name, (colnr_T)0)) { + continue; + } + + if (sid != -1 && sid != i) { continue; } @@ -2400,6 +2432,15 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) tv_dict_add_nr(d, S_LEN("version"), 1); // Vim9 autoload script (:h vim9-autoload), not applicable to Nvim. tv_dict_add_bool(d, S_LEN("autoload"), false); + + // When a filter pattern is specified to return information about only + // specific script(s), also add the script-local variables and + // functions. + if (sid != -1) { + dict_T *var_dict = tv_dict_copy(NULL, &si->sn_vars->sv_dict, true, get_copyID()); + tv_dict_add_dict(d, S_LEN("variables"), var_dict); + tv_dict_add_list(d, S_LEN("functions"), get_script_local_funcs((scid_T)sid)); + } } vim_regfree(regmatch.regprog); -- cgit From c5ec823a14f88a1d5ea1872f39fdabd85af1e81c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 15 Apr 2023 20:47:04 +0800 Subject: vim-patch:9.0.1431: getscriptinfo() loops even when specific SID is given Problem: getscriptinfo() loops even when specific SID is given. Solution: Only loop when needed. Give a clearer error message. (closes vim/vim#12207) https://github.com/vim/vim/commit/2d68b722e3bca7532eb0d83ce773934618f12db5 --- src/nvim/runtime.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index a659dba575..3eba2318ec 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2398,8 +2398,18 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) char *pat = NULL; if (argvars[0].v_type == VAR_DICT) { - sid = tv_dict_get_number_def(argvars[0].vval.v_dict, "sid", -1); - if (sid == -1) { + dictitem_T *sid_di = tv_dict_find(argvars[0].vval.v_dict, S_LEN("sid")); + if (sid_di != NULL) { + bool error = false; + sid = tv_get_number_chk(&sid_di->di_tv, &error); + if (error) { + return; + } + if (sid <= 0) { + semsg(e_invargNval, "sid", tv_get_string(&sid_di->di_tv)); + return; + } + } else { pat = tv_dict_get_string(argvars[0].vval.v_dict, "name", true); if (pat != NULL) { regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); @@ -2410,7 +2420,8 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } } - for (int i = 1; i <= script_items.ga_len; i++) { + for (varnumber_T i = sid > 0 ? sid : 1; + (i == sid || sid <= 0) && i <= script_items.ga_len; i++) { scriptitem_T *si = SCRIPT_ITEM(i); if (si->sn_name == NULL) { @@ -2421,10 +2432,6 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) continue; } - if (sid != -1 && sid != i) { - continue; - } - dict_T *d = tv_dict_alloc(); tv_list_append_dict(l, d); tv_dict_add_str(d, S_LEN("name"), si->sn_name); @@ -2433,10 +2440,9 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) // Vim9 autoload script (:h vim9-autoload), not applicable to Nvim. tv_dict_add_bool(d, S_LEN("autoload"), false); - // When a filter pattern is specified to return information about only - // specific script(s), also add the script-local variables and - // functions. - if (sid != -1) { + // When a script ID is specified, return information about only the + // specified script, and add the script-local variables and functions. + if (sid > 0) { dict_T *var_dict = tv_dict_copy(NULL, &si->sn_vars->sv_dict, true, get_copyID()); tv_dict_add_dict(d, S_LEN("variables"), var_dict); tv_dict_add_list(d, S_LEN("functions"), get_script_local_funcs((scid_T)sid)); -- cgit From 9770dcf96d77d734e2b88fc693c0f4fa0a17ef74 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 15 Apr 2023 21:05:55 +0800 Subject: refactor: remove FC_DEAD It's for Vim9 script only. --- src/nvim/runtime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 3eba2318ec..d091636e77 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2368,8 +2368,8 @@ static list_T *get_script_local_funcs(scid_T sid) // looking for functions with script ID "sid". HASHTAB_ITER(functbl, hi, { const ufunc_T *const fp = HI2UF(hi); - // Add active functions with script id == "sid" - if (!(fp->uf_flags & FC_DEAD) && (fp->uf_script_ctx.sc_sid == sid)) { + // Add functions with script id == "sid" + if (fp->uf_script_ctx.sc_sid == sid) { const char *const name = fp->uf_name_exp != NULL ? fp->uf_name_exp : fp->uf_name; tv_list_append_string(l, name, -1); } -- cgit From e83682e652ff68cf9a05f0076bb088e9231d2059 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 17 Apr 2023 19:22:55 +0800 Subject: refactor: suppress clang false positives (#23154) --- src/nvim/runtime.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index d091636e77..401139a89a 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -253,6 +253,7 @@ void ex_runtime(exarg_T *eap) int flags = eap->forceit ? DIP_ALL : 0; char *p = skiptowhite(arg); flags += get_runtime_cmd_flags(&arg, (size_t)(p - arg)); + assert(arg != NULL); // suppress clang false positive source_runtime(arg, flags); } -- cgit From aee6f08ce12a62e9104892702a658a8d3daee4df Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 17 Apr 2023 13:08:53 +0200 Subject: fix(runtime): do not allow breakcheck inside runtime path calculation problem: breakcheck might run arbitrary lua code, which might require modules and thus invoke runtime path calculation recursively. solution: Block the use of breakcheck when expanding glob patterns inside 'runtimepath' fixes #23012 --- src/nvim/runtime.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 401139a89a..a6ed5c7410 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -470,7 +470,8 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c } int ew_flags = ((flags & DIP_DIR) ? EW_DIR : EW_FILE) - | (flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0; + | ((flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0) + | EW_NOBREAK; // Expand wildcards, invoke the callback for each match. char *(pat[]) = { buf }; @@ -670,7 +671,7 @@ static void expand_rtp_entry(RuntimeSearchPath *search_path, Map(String, handle_ int num_files; char **files; char *(pat[]) = { entry }; - if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR) == OK) { + if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR | EW_NOBREAK) == OK) { for (int i = 0; i < num_files; i++) { push_path(search_path, rtp_used, files[i], after); } -- cgit From 3b0df1780e2c8526bda5dead18ee7cc45925caba Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 26 Apr 2023 23:23:44 +0200 Subject: refactor: uncrustify Notable changes: replace all infinite loops to `while(true)` and remove `int` from `unsigned int`. --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index a6ed5c7410..2d82ff1bba 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2558,7 +2558,7 @@ static char *get_one_sourceline(struct source_cookie *sp) // Loop until there is a finished line (or end-of-file). sp->sourcing_lnum++; - for (;;) { + while (true) { // make room to read at least 120 (more) characters ga_grow(&ga, 120); buf = ga.ga_data; -- cgit From ff34c91194f9ab9d02808f2880029c38a4655eb5 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Mon, 17 Apr 2023 17:23:47 +0100 Subject: vim-patch:9.0.1330: handling new value of an option has a long "else if" chain Problem: Handling new value of an option has a long "else if" chain. Solution: Use a function pointer. (Yegappan Lakshmanan, closes vim/vim#12015) https://github.com/vim/vim/commit/af93691b53f38784efce0b93fe7644c44a7e382e --- src/nvim/runtime.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 2d82ff1bba..b4a23d544e 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -780,9 +780,10 @@ RuntimeSearchPath runtime_search_path_build(void) return search_path; } -void runtime_search_path_invalidate(void) +const char *did_set_runtimepackpath(optset_T *args) { runtime_search_path_valid = false; + return NULL; } void runtime_search_path_free(RuntimeSearchPath path) -- cgit From e64db1d284f0b89672f1ccf89018a88a63865cd6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 8 May 2023 08:26:00 +0800 Subject: vim-patch:9.0.1523: some error messages are not marked for translation (#23529) Problem: Some error messages are not marked for translation. Solution: Surround the messages in _(). (closes vim/vim#12356) https://github.com/vim/vim/commit/276410e78f0b82e3123059383994d2f4c578dfbd --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index b4a23d544e..34e94d6021 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2409,7 +2409,7 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } if (sid <= 0) { - semsg(e_invargNval, "sid", tv_get_string(&sid_di->di_tv)); + semsg(_(e_invargNval), "sid", tv_get_string(&sid_di->di_tv)); return; } } else { -- cgit From d36dd2bae8e899b40cc21603e600a5046213bc36 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Tue, 16 May 2023 05:33:03 +0200 Subject: refactor: use xstrl{cpy,cat} on IObuff (#23648) Replace usage of STR{CPY,CAT} with xstrl{cpy,cat} when using on IObuff Co-authored-by: ii14 --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 34e94d6021..8763655de9 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1547,7 +1547,7 @@ static inline char *add_dir(char *dest, const char *const dir, const size_t dir_ xstrlcpy(IObuff, appname, appname_len + 1); #if defined(MSWIN) if (type == kXDGDataHome || type == kXDGStateHome) { - STRCAT(IObuff, "-data"); + xstrlcat(IObuff, "-data", IOSIZE); appname_len += 5; } #endif -- cgit From e2fdd53d8c015913e8be4ff708fc3488558c8906 Mon Sep 17 00:00:00 2001 From: bfredl Date: Sun, 14 May 2023 18:45:56 +0200 Subject: refactor(map): avoid duplicated khash_t types for values This reduces the total number of khash_t instantiations from 22 to 8. Make the khash internal functions take the size of values as a runtime parameter. This is abstracted with typesafe Map containers which are still specialized for both key, value type. Introduce `Set(key)` type for when there is no value. Refactor shada.c to use Map/Set instead of khash directly. This requires `map_ref` operation to be more flexible. Return pointers to both key and value, plus an indicator for new_item. As a bonus, `map_key` is now redundant. Instead of Map(cstr_t, FileMarks), use a pointer map as the FileMarks struct is humongous. Make `event_strings` actually work like an intern pool instead of wtf it was doing before. --- src/nvim/runtime.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 34e94d6021..f7b7723553 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -646,21 +646,20 @@ int do_in_path_and_pp(char *path, char *name, int flags, DoInRuntimepathCB callb return done; } -static void push_path(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, char *entry, +static void push_path(RuntimeSearchPath *search_path, Set(String) *rtp_used, char *entry, bool after) { - handle_T h = map_get(String, handle_T)(rtp_used, cstr_as_string(entry)); - if (h == 0) { - char *allocated = xstrdup(entry); - map_put(String, handle_T)(rtp_used, cstr_as_string(allocated), 1); - kv_push(*search_path, ((SearchPathItem){ allocated, after, kNone })); + String *key_alloc; + if (set_put_ref(String, rtp_used, cstr_as_string(entry), &key_alloc)) { + *key_alloc = cstr_to_string(entry); + kv_push(*search_path, ((SearchPathItem){ key_alloc->data, after, kNone })); } } -static void expand_rtp_entry(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, - char *entry, bool after) +static void expand_rtp_entry(RuntimeSearchPath *search_path, Set(String) *rtp_used, char *entry, + bool after) { - if (map_get(String, handle_T)(rtp_used, cstr_as_string(entry))) { + if (set_has(String, rtp_used, cstr_as_string(entry))) { return; } @@ -679,7 +678,7 @@ static void expand_rtp_entry(RuntimeSearchPath *search_path, Map(String, handle_ } } -static void expand_pack_entry(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, +static void expand_pack_entry(RuntimeSearchPath *search_path, Set(String) *rtp_used, CharVec *after_path, char *pack_entry, size_t pack_entry_len) { static char buf[MAXPATHL]; @@ -712,10 +711,8 @@ static bool path_is_after(char *buf, size_t buflen) RuntimeSearchPath runtime_search_path_build(void) { kvec_t(String) pack_entries = KV_INITIAL_VALUE; - // TODO(bfredl): these should just be sets, when Set(String) is do merge to - // master. Map(String, handle_T) pack_used = MAP_INIT; - Map(String, handle_T) rtp_used = MAP_INIT; + Set(String) rtp_used = SET_INIT; RuntimeSearchPath search_path = KV_INITIAL_VALUE; CharVec after_path = KV_INITIAL_VALUE; @@ -744,7 +741,7 @@ RuntimeSearchPath runtime_search_path_build(void) // fact: &rtp entries can contain wild chars expand_rtp_entry(&search_path, &rtp_used, buf, false); - handle_T *h = map_ref(String, handle_T)(&pack_used, cstr_as_string(buf), false); + handle_T *h = map_ref(String, handle_T)(&pack_used, cstr_as_string(buf), NULL); if (h) { (*h)++; expand_pack_entry(&search_path, &rtp_used, &after_path, buf, buflen); @@ -774,8 +771,8 @@ RuntimeSearchPath runtime_search_path_build(void) // strings are not owned kv_destroy(pack_entries); kv_destroy(after_path); - map_destroy(String, handle_T)(&pack_used); - map_destroy(String, handle_T)(&rtp_used); + map_destroy(String, &pack_used); + set_destroy(String, &rtp_used); return search_path; } -- cgit From cfd4fdfea4d0e68ea50ad412b88b5289ded6fd6f Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Tue, 23 May 2023 14:25:10 +0600 Subject: refactor(api): new helper macros Adds new API helper macros `CSTR_AS_OBJ()`, `STATIC_CSTR_AS_OBJ()`, and `STATIC_CSTR_TO_OBJ()`, which cleans up a lot of the current code. These macros will also be used extensively in the upcoming option refactor PRs because then API Objects will be used to get/set options. This PR also modifies pre-existing code to use old API helper macros like `CSTR_TO_OBJ()` to make them cleaner. --- src/nvim/runtime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index a9068fabc8..4b27067fb8 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -512,7 +512,7 @@ Array runtime_inspect(void) for (size_t i = 0; i < kv_size(path); i++) { SearchPathItem *item = &kv_A(path, i); Array entry = ARRAY_DICT_INIT; - ADD(entry, STRING_OBJ(cstr_to_string(item->path))); + ADD(entry, CSTR_TO_OBJ(item->path)); ADD(entry, BOOLEAN_OBJ(item->after)); if (item->has_lua != kNone) { ADD(entry, BOOLEAN_OBJ(item->has_lua == kTrue)); @@ -568,7 +568,7 @@ ArrayOf(String) runtime_get_named_common(bool lua, Array pat, bool all, item->path, pat_item.data.string.data); if (size < buf_len) { if (os_file_is_readable(buf)) { - ADD(rv, STRING_OBJ(cstr_to_string(buf))); + ADD(rv, CSTR_TO_OBJ(buf)); if (!all) { goto done; } -- cgit From 4b60267f82ef1947f8a583c02eaf502cf1db69ca Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 2 Jun 2023 21:00:55 +0800 Subject: feat(:source): source current ft=lua buffer as Lua code (#23802) --- src/nvim/runtime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 4b27067fb8..964e2d0933 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1926,8 +1926,8 @@ static void cmd_source_buffer(const exarg_T *const eap) .buf = ga.ga_data, .offset = 0, }; - if (curbuf->b_fname - && path_with_extension(curbuf->b_fname, "lua")) { + if (strequal(curbuf->b_p_ft, "lua") + || (curbuf->b_fname && path_with_extension(curbuf->b_fname, "lua"))) { nlua_source_using_linegetter(get_str_line, (void *)&cookie, ":source (no file)"); } else { source_using_linegetter((void *)&cookie, get_str_line, ":source (no file)"); -- cgit From b3d5138fd0066fda26ef7724a542ae45eb42fc84 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Wed, 7 Jun 2023 06:05:16 +0600 Subject: refactor(options): remove `getoption_T` and introduce `OptVal` (#23850) Removes the `getoption_T` struct and also introduces the `OptVal` struct to unify the methods of getting/setting different option value types. This is the first of many PRs to reduce code duplication in the Vim option code as well as to make options easier to maintain. It also increases the flexibility and extensibility of options. Which opens the door for things like Array and Dictionary options. --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 964e2d0933..70d7261973 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1006,7 +1006,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) xstrlcat(new_rtp, afterdir, new_rtp_capacity); } - set_option_value_give_err("rtp", 0L, new_rtp, 0); + set_option_value_give_err("rtp", CSTR_AS_OPTVAL(new_rtp), 0); xfree(new_rtp); retval = OK; -- cgit From 2f17ef1fc4b96cf1106fd95ba090d34a2e4b977b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 22 Jun 2023 04:09:14 -0700 Subject: fix(messages): use "Vimscript" instead of "VimL" #24111 followup to #24109 fix #16150 --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 70d7261973..0503c08af9 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1770,7 +1770,7 @@ static FILE *fopen_noinh_readbin(char *filename) return fdopen(fd_tmp, READBIN); } -/// Concatenate VimL line if it starts with a line continuation into a growarray +/// Concatenate Vimscript line if it starts with a line continuation into a growarray /// (excluding the continuation chars and leading whitespace) /// /// @note Growsize of the growarray may be changed to speed up concatenations! -- cgit From fbeef0d4ef1aadc4e50b9f33946cf4dca8ca6b62 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 8 Jul 2023 23:29:24 +0800 Subject: fix(completion): don't add backslashes to runtime pattern (#24296) Problem: Bashslashes added as regexp in runtime completion may be treated as path separator with some 'isfname' value. Solution: Make curly braces work for runtime completion and use it. --- src/nvim/runtime.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 0503c08af9..679f4c2662 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -338,7 +338,7 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo } int ew_flags = ((flags & DIP_DIR) ? EW_DIR : EW_FILE) - | (flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0; + | ((flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0); // Expand wildcards, invoke the callback for each match. if (gen_expand_wildcards(1, &buf, &num_files, &files, ew_flags) == OK) { @@ -1222,9 +1222,9 @@ static void ExpandRTDir_int(char *pat, size_t pat_len, int flags, bool keep_ext, bool expand_dirs = false; if (*dirnames[i] == NUL) { // empty dir used for :runtime - snprintf(tail, tail_buflen, "%s*.\\(vim\\|lua\\)", pat); + snprintf(tail, tail_buflen, "%s*.{vim,lua}", pat); } else { - snprintf(tail, tail_buflen, "%s/%s*.\\(vim\\|lua\\)", dirnames[i], pat); + snprintf(tail, tail_buflen, "%s/%s*.{vim,lua}", dirnames[i], pat); } expand: -- cgit From 516b173780e39de3ce1e4525f0a8f0ff250c992b Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 13 Jul 2023 10:17:19 +0100 Subject: perf(rtp): reduce rtp scans (#24191) * perf(rtp): reduce rtp scans Problem: Scanning the filesystem is expensive and particularly affects startuptime. Solution: Reduce the amount of redundant directory scans by relying less on glob patterns and handle vim and lua sourcing lower down. --- src/nvim/runtime.c | 245 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 157 insertions(+), 88 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 679f4c2662..eac483b8e7 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -269,9 +269,55 @@ void set_context_in_runtime_cmd(expand_T *xp, const char *arg) xp->xp_pattern = (char *)arg; } -static void source_callback(char *fname, void *cookie) +/// Source all .vim and .lua files in "fnames" with .vim files being sourced first. +static bool source_callback_vim_lua(int num_fnames, char **fnames, bool all, void *cookie) { - (void)do_source(fname, false, DOSO_NONE, cookie); + bool did_one = false; + + for (int i = 0; i < num_fnames; i++) { + if (str_ends_with(fnames[i], ".vim")) { + (void)do_source(fnames[i], false, DOSO_NONE, cookie); + did_one = true; + if (!all) { + return true; + } + } + } + + for (int i = 0; i < num_fnames; i++) { + if (str_ends_with(fnames[i], ".lua")) { + (void)do_source(fnames[i], false, DOSO_NONE, cookie); + did_one = true; + if (!all) { + return true; + } + } + } + + return did_one; +} + +/// Source all files in "fnames" with .vim files sourced first, .lua files +/// sourced second, and any remaining files sourced last. +static bool source_callback(int num_fnames, char **fnames, bool all, void *cookie) +{ + bool did_one = source_callback_vim_lua(num_fnames, fnames, all, cookie); + + if (!all && did_one) { + return true; + } + + for (int i = 0; i < num_fnames; i++) { + if (!str_ends_with(fnames[i], ".vim") && !str_ends_with(fnames[i], ".lua")) { + (void)do_source(fnames[i], false, DOSO_NONE, cookie); + did_one = true; + if (!all) { + return true; + } + } + } + + return did_one; } /// Find the file "name" in all directories in "path" and invoke @@ -284,8 +330,6 @@ static void source_callback(char *fname, void *cookie) /// return FAIL when no file could be sourced, OK otherwise. int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, void *cookie) { - int num_files; - char **files; bool did_one = false; // Make a copy of 'runtimepath'. Invoking the callback may change the @@ -300,9 +344,11 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo verbose_leave(); } + bool do_all = (flags & DIP_ALL) != 0; + // Loop over all entries in 'runtimepath'. char *rtp = rtp_copy; - while (*rtp != NUL && ((flags & DIP_ALL) || !did_one)) { + while (*rtp != NUL && (do_all || !did_one)) { // Copy the path from 'runtimepath' to buf[]. copy_option_part(&rtp, buf, MAXPATHL, ","); size_t buflen = strlen(buf); @@ -318,7 +364,7 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo } if (name == NULL) { - (*callback)(buf, cookie); + (*callback)(1, &buf, do_all, cookie); did_one = true; } else if (buflen + strlen(name) + 2 < MAXPATHL) { add_pathsep(buf); @@ -326,7 +372,7 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo // Loop over all patterns in "name" char *np = name; - while (*np != NUL && ((flags & DIP_ALL) || !did_one)) { + while (*np != NUL && (do_all || !did_one)) { // Append the pattern from "name" to buf[]. assert(MAXPATHL >= (tail - buf)); copy_option_part(&np, tail, (size_t)(MAXPATHL - (tail - buf)), "\t "); @@ -340,17 +386,8 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo int ew_flags = ((flags & DIP_DIR) ? EW_DIR : EW_FILE) | ((flags & DIP_DIRFILE) ? (EW_DIR|EW_FILE) : 0); - // Expand wildcards, invoke the callback for each match. - if (gen_expand_wildcards(1, &buf, &num_files, &files, ew_flags) == OK) { - for (int i = 0; i < num_files; i++) { - (*callback)(files[i], cookie); - did_one = true; - if (!(flags & DIP_ALL)) { - break; - } - } - FreeWild(num_files, files); - } + did_one |= gen_expand_wildcards_and_cb(1, &buf, ew_flags, do_all, callback, + cookie) == OK; } } } @@ -421,8 +458,6 @@ void runtime_search_path_unref(RuntimeSearchPath path, const int *ref) int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *cookie) { char *tail; - int num_files; - char **files; bool did_one = false; char buf[MAXPATHL]; @@ -436,6 +471,8 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c int ref; RuntimeSearchPath path = runtime_search_path_get_cached(&ref); + bool do_all = (flags & DIP_ALL) != 0; + // Loop over all entries in cached path for (size_t j = 0; j < kv_size(path); j++) { SearchPathItem item = kv_A(path, j); @@ -450,7 +487,7 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c } if (name == NULL) { - (*callback)(item.path, cookie); + (*callback)(1, &item.path, do_all, cookie); } else if (buflen + strlen(name) + 2 < MAXPATHL) { STRCPY(buf, item.path); add_pathsep(buf); @@ -458,7 +495,8 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c // Loop over all patterns in "name" char *np = name; - while (*np != NUL && ((flags & DIP_ALL) || !did_one)) { + + while (*np != NUL && (do_all || !did_one)) { // Append the pattern from "name" to buf[]. assert(MAXPATHL >= (tail - buf)); copy_option_part(&np, tail, (size_t)(MAXPATHL - (tail - buf)), "\t "); @@ -475,16 +513,7 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c // Expand wildcards, invoke the callback for each match. char *(pat[]) = { buf }; - if (gen_expand_wildcards(1, pat, &num_files, &files, ew_flags) == OK) { - for (int i = 0; i < num_files; i++) { - (*callback)(files[i], cookie); - did_one = true; - if (!(flags & DIP_ALL)) { - break; - } - } - FreeWild(num_files, files); - } + did_one |= gen_expand_wildcards_and_cb(1, pat, ew_flags, do_all, callback, cookie) == OK; } } } @@ -841,27 +870,46 @@ int source_runtime(char *name, int flags) return do_in_runtimepath(name, flags, source_callback, NULL); } -/// Just like source_runtime(), but use "path" instead of 'runtimepath'. -int source_in_path(char *path, char *name, int flags) +/// Just like source_runtime(), but only source vim and lua files +int source_runtime_vim_lua(char *name, int flags) +{ + return do_in_runtimepath(name, flags, source_callback_vim_lua, NULL); +} + +/// Just like source_runtime(), but: +/// - use "path" instead of 'runtimepath'. +/// - only source .vim and .lua files +int source_in_path_vim_lua(char *path, char *name, int flags) { - return do_in_path_and_pp(path, name, flags, source_callback, NULL); + return do_in_path_and_pp(path, name, flags, source_callback_vim_lua, NULL); } -// Expand wildcards in "pat" and invoke do_source()/nlua_exec_file() -// for each match. -static void source_all_matches(char *pat) +/// Expand wildcards in "pats" and invoke callback matches. +/// +/// @param num_pat is number of input patterns. +/// @param patx is an array of pointers to input patterns. +/// @param flags is a combination of EW_* flags used in +/// expand_wildcards(). +/// @param all invoke callback on all matches or just one +/// @param callback called for each match. +/// @param cookie context for callback +/// +/// @returns OK when some files were found, FAIL otherwise. +static int gen_expand_wildcards_and_cb(int num_pat, char **pats, int flags, bool all, + DoInRuntimepathCB callback, void *cookie) { int num_files; char **files; - if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) != OK) { - return; + if (gen_expand_wildcards(num_pat, pats, &num_files, &files, flags) != OK) { + return FAIL; } - for (int i = 0; i < num_files; i++) { - (void)do_source(files[i], false, DOSO_NONE, NULL); - } + (*callback)(num_files, files, all, cookie); + FreeWild(num_files, files); + + return OK; } /// Add the package directory to 'runtimepath' @@ -1022,16 +1070,14 @@ theend: /// load these from filetype.vim) static int load_pack_plugin(bool opt, char *fname) { - static const char *ftpat = "%s/ftdetect/*.vim"; // NOLINT + static const char *ftpat = "%s/ftdetect/*"; // NOLINT char *const ffname = fix_fname(fname); size_t len = strlen(ffname) + strlen(ftpat); char *pat = xmallocz(len); - vim_snprintf(pat, len, "%s/plugin/**/*.vim", ffname); // NOLINT - source_all_matches(pat); - vim_snprintf(pat, len, "%s/plugin/**/*.lua", ffname); // NOLINT - source_all_matches(pat); + vim_snprintf(pat, len, "%s/plugin/**/*", ffname); // NOLINT + gen_expand_wildcards_and_cb(1, &pat, EW_FILE, true, source_callback_vim_lua, NULL); char *cmd = xstrdup("g:did_load_filetypes"); @@ -1040,9 +1086,7 @@ static int load_pack_plugin(bool opt, char *fname) if (opt && eval_to_number(cmd) > 0) { do_cmdline_cmd("augroup filetypedetect"); vim_snprintf(pat, len, ftpat, ffname); - source_all_matches(pat); - vim_snprintf(pat, len, "%s/ftdetect/*.lua", ffname); // NOLINT - source_all_matches(pat); + gen_expand_wildcards_and_cb(1, &pat, EW_FILE, true, source_callback_vim_lua, NULL); do_cmdline_cmd("augroup END"); } xfree(cmd); @@ -1057,42 +1101,62 @@ static int APP_ADD_DIR; static int APP_LOAD; static int APP_BOTH; -static void add_pack_plugin(bool opt, char *fname, void *cookie) +static void add_pack_plugins(bool opt, int num_fnames, char **fnames, bool all, void *cookie) { + bool did_one = false; + if (cookie != &APP_LOAD) { char *buf = xmalloc(MAXPATHL); - bool found = false; - - const char *p = p_rtp; - while (*p != NUL) { - copy_option_part((char **)&p, buf, MAXPATHL, ","); - if (path_fnamecmp(buf, fname) == 0) { - found = true; + for (int i = 0; i < num_fnames; i++) { + bool found = false; + + const char *p = p_rtp; + while (*p != NUL) { + copy_option_part((char **)&p, buf, MAXPATHL, ","); + if (path_fnamecmp(buf, fnames[i]) == 0) { + found = true; + break; + } + } + if (!found) { + // directory is not yet in 'runtimepath', add it + if (add_pack_dir_to_rtp(fnames[i], false) == FAIL) { + xfree(buf); + return; + } + } + did_one = true; + if (!all) { break; } } xfree(buf); - if (!found) { - // directory is not yet in 'runtimepath', add it - if (add_pack_dir_to_rtp(fname, false) == FAIL) { - return; - } - } + } + + if (!all && did_one) { + return; } if (cookie != &APP_ADD_DIR) { - load_pack_plugin(opt, fname); + for (int i = 0; i < num_fnames; i++) { + load_pack_plugin(opt, fnames[i]); + if (!all) { + break; + } + } } } -static void add_start_pack_plugin(char *fname, void *cookie) +static bool add_start_pack_plugins(int num_fnames, char **fnames, bool all, void *cookie) { - add_pack_plugin(false, fname, cookie); + add_pack_plugins(false, num_fnames, fnames, all, cookie); + return num_fnames > 0; } -static void add_opt_pack_plugin(char *fname, void *cookie) +static bool add_opt_pack_plugins(int num_fnames, char **fnames, bool all, void *cookie) { - add_pack_plugin(true, fname, cookie); + add_pack_plugins(true, num_fnames, fnames, all, cookie); + return num_fnames > 0; } /// Add all packages in the "start" directory to 'runtimepath'. @@ -1112,20 +1176,28 @@ static bool pack_has_entries(char *buf) return num_files > 0; } -static void add_pack_start_dir(char *fname, void *cookie) +static bool add_pack_start_dir(int num_fnames, char **fnames, bool all, void *cookie) { static char buf[MAXPATHL]; - char *(start_pat[]) = { "/start/*", "/pack/*/start/*" }; // NOLINT - for (int i = 0; i < 2; i++) { - if (strlen(fname) + strlen(start_pat[i]) + 1 > MAXPATHL) { - continue; + for (int i = 0; i < num_fnames; i++) { + char *(start_pat[]) = { "/start/*", "/pack/*/start/*" }; // NOLINT + for (int j = 0; j < 2; j++) { + if (strlen(fnames[i]) + strlen(start_pat[j]) + 1 > MAXPATHL) { + continue; + } + xstrlcpy(buf, fnames[i], MAXPATHL); + xstrlcat(buf, start_pat[j], sizeof buf); + if (pack_has_entries(buf)) { + add_pack_dir_to_rtp(buf, true); + } } - xstrlcpy(buf, fname, MAXPATHL); - xstrlcat(buf, start_pat[i], sizeof buf); - if (pack_has_entries(buf)) { - add_pack_dir_to_rtp(buf, true); + + if (!all) { + break; } } + + return num_fnames > 1; } /// Load plugins from all packages in the "start" directory. @@ -1133,9 +1205,9 @@ void load_start_packages(void) { did_source_packages = true; do_in_path(p_pp, "pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT - add_start_pack_plugin, &APP_LOAD); + add_start_pack_plugins, &APP_LOAD); do_in_path(p_pp, "start/*", DIP_ALL + DIP_DIR, // NOLINT - add_start_pack_plugin, &APP_LOAD); + add_start_pack_plugins, &APP_LOAD); } // ":packloadall" @@ -1156,8 +1228,7 @@ void load_plugins(void) { if (p_lpl) { char *rtp_copy = p_rtp; - char *const plugin_pattern_vim = "plugin/**/*.vim"; // NOLINT - char *const plugin_pattern_lua = "plugin/**/*.lua"; // NOLINT + char *const plugin_pattern = "plugin/**/*"; // NOLINT if (!did_source_packages) { rtp_copy = xstrdup(p_rtp); @@ -1165,8 +1236,7 @@ void load_plugins(void) } // don't use source_runtime() yet so we can check for :packloadall below - source_in_path(rtp_copy, plugin_pattern_vim, DIP_ALL | DIP_NOAFTER); - source_in_path(rtp_copy, plugin_pattern_lua, DIP_ALL | DIP_NOAFTER); + source_in_path_vim_lua(rtp_copy, plugin_pattern, DIP_ALL | DIP_NOAFTER); TIME_MSG("loading rtp plugins"); // Only source "start" packages if not done already with a :packloadall @@ -1177,8 +1247,7 @@ void load_plugins(void) } TIME_MSG("loading packages"); - source_runtime(plugin_pattern_vim, DIP_ALL | DIP_AFTER); - source_runtime(plugin_pattern_lua, DIP_ALL | DIP_AFTER); + source_runtime_vim_lua(plugin_pattern, DIP_ALL | DIP_AFTER); TIME_MSG("loading after plugins"); } } @@ -1203,7 +1272,7 @@ void ex_packadd(exarg_T *eap) // only when nothing was found in the first round. res = do_in_path(p_pp, pat, DIP_ALL + DIP_DIR + (round == 2 && res == FAIL ? DIP_ERR : 0), - round == 1 ? add_start_pack_plugin : add_opt_pack_plugin, + round == 1 ? add_start_pack_plugins : add_opt_pack_plugins, eap->forceit ? &APP_ADD_DIR : &APP_BOTH); xfree(pat); } -- cgit From dbb840da01c72d8a311e0c55d3248d78a64b63a4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 14 Jul 2023 06:46:16 +0800 Subject: fix(runtime): respect 'rtp' order for all runtime files (#24335) --- src/nvim/runtime.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index eac483b8e7..9cd4a17b27 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1067,21 +1067,22 @@ theend: /// Load scripts in "plugin" directory of the package. /// For opt packages, also load scripts in "ftdetect" (start packages already -/// load these from filetype.vim) +/// load these from filetype.lua) static int load_pack_plugin(bool opt, char *fname) { - static const char *ftpat = "%s/ftdetect/*"; // NOLINT + static const char plugpat[] = "%s/plugin/**/*"; // NOLINT + static const char ftpat[] = "%s/ftdetect/*"; // NOLINT char *const ffname = fix_fname(fname); - size_t len = strlen(ffname) + strlen(ftpat); + size_t len = strlen(ffname) + sizeof(plugpat); char *pat = xmallocz(len); - vim_snprintf(pat, len, "%s/plugin/**/*", ffname); // NOLINT + vim_snprintf(pat, len, plugpat, ffname); // NOLINT gen_expand_wildcards_and_cb(1, &pat, EW_FILE, true, source_callback_vim_lua, NULL); char *cmd = xstrdup("g:did_load_filetypes"); - // If runtime/filetype.vim wasn't loaded yet, the scripts will be + // If runtime/filetype.lua wasn't loaded yet, the scripts will be // found when it loads. if (opt && eval_to_number(cmd) > 0) { do_cmdline_cmd("augroup filetypedetect"); @@ -1255,7 +1256,7 @@ void load_plugins(void) /// ":packadd[!] {name}" void ex_packadd(exarg_T *eap) { - static const char *plugpat = "pack/*/%s/%s"; // NOLINT + static const char plugpat[] = "pack/*/%s/%s"; // NOLINT int res = OK; // Round 1: use "start", round 2: use "opt". @@ -1265,7 +1266,7 @@ void ex_packadd(exarg_T *eap) continue; } - const size_t len = strlen(plugpat) + strlen(eap->arg) + 5; + const size_t len = sizeof(plugpat) + strlen(eap->arg) + 5; char *pat = xmallocz(len); vim_snprintf(pat, len, plugpat, round == 1 ? "start" : "opt", eap->arg); // The first round don't give a "not found" error, in the second round @@ -1367,11 +1368,11 @@ expand: /// Expand color scheme, compiler or filetype names. /// Search from 'runtimepath': -/// 'runtimepath'/{dirnames}/{pat}.(vim|lua) +/// 'runtimepath'/{dirnames}/{pat}.{vim,lua} /// When "flags" has DIP_START: search also from "start" of 'packpath': -/// 'packpath'/pack/*/start/*/{dirnames}/{pat}.(vim|lua) +/// 'packpath'/pack/*/start/*/{dirnames}/{pat}.{vim,lua} /// When "flags" has DIP_OPT: search also from "opt" of 'packpath': -/// 'packpath'/pack/*/opt/*/{dirnames}/{pat}.(vim|lua) +/// 'packpath'/pack/*/opt/*/{dirnames}/{pat}.{vim,lua} /// "dirnames" is an array with one or more directory names. int ExpandRTDir(char *pat, int flags, int *num_file, char ***file, char *dirnames[]) { -- cgit From 9176b5e10a6b32ff65c8ba3f532e3bd55c168ec6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 14 Jul 2023 07:57:13 +0800 Subject: fix(runtime): respect 'fileignorecase' when sourcing (#24344) --- src/nvim/runtime.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 9cd4a17b27..9614937c4c 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -275,7 +275,7 @@ static bool source_callback_vim_lua(int num_fnames, char **fnames, bool all, voi bool did_one = false; for (int i = 0; i < num_fnames; i++) { - if (str_ends_with(fnames[i], ".vim")) { + if (path_with_extension(fnames[i], "vim")) { (void)do_source(fnames[i], false, DOSO_NONE, cookie); did_one = true; if (!all) { @@ -285,7 +285,7 @@ static bool source_callback_vim_lua(int num_fnames, char **fnames, bool all, voi } for (int i = 0; i < num_fnames; i++) { - if (str_ends_with(fnames[i], ".lua")) { + if (path_with_extension(fnames[i], "lua")) { (void)do_source(fnames[i], false, DOSO_NONE, cookie); did_one = true; if (!all) { @@ -308,7 +308,8 @@ static bool source_callback(int num_fnames, char **fnames, bool all, void *cooki } for (int i = 0; i < num_fnames; i++) { - if (!str_ends_with(fnames[i], ".vim") && !str_ends_with(fnames[i], ".lua")) { + if (!path_with_extension(fnames[i], "vim") + && !path_with_extension(fnames[i], "lua")) { (void)do_source(fnames[i], false, DOSO_NONE, cookie); did_one = true; if (!all) { -- cgit From ab5cdbd167353a0c6a0ef0b864d78af13029339c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 19 Jul 2023 07:14:32 +0800 Subject: test(startup_spec): add a test for #18315 (#24391) --- src/nvim/runtime.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 9614937c4c..290b773371 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1237,7 +1237,8 @@ void load_plugins(void) add_pack_start_dirs(); } - // don't use source_runtime() yet so we can check for :packloadall below + // Don't use source_runtime_vim_lua() yet so we can check for :packloadall below. + // NB: after calling this "rtp_copy" may have been freed if it wasn't copied. source_in_path_vim_lua(rtp_copy, plugin_pattern, DIP_ALL | DIP_NOAFTER); TIME_MSG("loading rtp plugins"); -- cgit From 19d7fb8efeaeb84bc639282de1510b7e8962d49a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 18 Aug 2023 06:20:06 +0800 Subject: vim-patch:9.0.1734: :runtime completion fails for multiple args (#24767) Problem: :runtime completion fails for multiple args Solution: Make it work closes: vim/vim#12616 https://github.com/vim/vim/commit/be5cdd1d634c2dfc7e415499fb18f4d246a8721c --- src/nvim/runtime.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 290b773371..89ffecd333 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -265,6 +265,15 @@ void set_context_in_runtime_cmd(expand_T *xp, const char *arg) char *p = skiptowhite(arg); runtime_expand_flags = *p != NUL ? get_runtime_cmd_flags((char **)&arg, (size_t)(p - arg)) : 0; + // Skip to the last argument. + while (*(p = skiptowhite_esc(arg)) != NUL) { + if (runtime_expand_flags == 0) { + // When there are multiple arguments and [where] is not specified, + // use an unrelated non-zero flag to avoid expanding [where]. + runtime_expand_flags = DIP_ALL; + } + arg = skipwhite(p); + } xp->xp_context = EXPAND_RUNTIME; xp->xp_pattern = (char *)arg; } -- cgit From 46163ddf5d718c4e749df78ef8e54d0715de6cb9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 18 Aug 2023 08:24:49 +0800 Subject: vim-patch:9.0.1730: passing multiple patterns to runtime not working (#24771) Problem: passing multiple patterns to runtime not working Solution: prepend prefix to each argument separately closes: vim/vim#12617 https://github.com/vim/vim/commit/008c91537b55835aa91cd8fbe1a139256581da31 --- src/nvim/runtime.c | 70 ++++++++++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 44 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 89ffecd333..992566b0fe 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -330,15 +330,17 @@ static bool source_callback(int num_fnames, char **fnames, bool all, void *cooki return did_one; } -/// Find the file "name" in all directories in "path" and invoke +/// Find the patterns in "name" in all directories in "path" and invoke /// "callback(fname, cookie)". -/// "name" can contain wildcards. +/// "prefix" is prepended to each pattern in "name". /// When "flags" has DIP_ALL: source all files, otherwise only the first one. /// When "flags" has DIP_DIR: find directories instead of files. /// When "flags" has DIP_ERR: give an error message if there is no match. /// -/// return FAIL when no file could be sourced, OK otherwise. -int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, void *cookie) +/// Return FAIL when no file could be sourced, OK otherwise. +int do_in_path(const char *path, const char *prefix, char *name, int flags, + DoInRuntimepathCB callback, void *cookie) + FUNC_ATTR_NONNULL_ARG(1, 2) { bool did_one = false; @@ -350,7 +352,11 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo char *tail; if (p_verbose > 10 && name != NULL) { verbose_enter(); - smsg(_("Searching for \"%s\" in \"%s\""), name, path); + if (*prefix != NUL) { + smsg(_("Searching for \"%s\" under \"%s\" in \"%s\""), name, prefix, path); + } else { + smsg(_("Searching for \"%s\" in \"%s\""), name, path); + } verbose_leave(); } @@ -376,8 +382,9 @@ int do_in_path(char *path, char *name, int flags, DoInRuntimepathCB callback, vo if (name == NULL) { (*callback)(1, &buf, do_all, cookie); did_one = true; - } else if (buflen + strlen(name) + 2 < MAXPATHL) { + } else if (buflen + 2 + strlen(prefix) + strlen(name) < MAXPATHL) { add_pathsep(buf); + STRCAT(buf, prefix); tail = buf + strlen(buf); // Loop over all patterns in "name" @@ -633,52 +640,26 @@ int do_in_path_and_pp(char *path, char *name, int flags, DoInRuntimepathCB callb int done = FAIL; if ((flags & DIP_NORTP) == 0) { - done |= do_in_path(path, (name && !*name) ? NULL : name, flags, callback, + done |= do_in_path(path, "", (name && !*name) ? NULL : name, flags, callback, cookie); } if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START)) { - char *start_dir = "pack/*/start/*/%s%s"; // NOLINT - size_t len = strlen(start_dir) + strlen(name) + 6; - char *s = xmallocz(len); // TODO(bfredl): get rid of random allocations - char *suffix = (flags & DIP_AFTER) ? "after/" : ""; - - vim_snprintf(s, len, start_dir, suffix, name); - done |= do_in_path(p_pp, s, flags & ~DIP_AFTER, callback, cookie); - - xfree(s); + const char *prefix + = (flags & DIP_AFTER) ? "pack/*/start/*/after/" : "pack/*/start/*/"; // NOLINT + done |= do_in_path(p_pp, prefix, name, flags & ~DIP_AFTER, callback, cookie); if (done == FAIL || (flags & DIP_ALL)) { - start_dir = "start/*/%s%s"; // NOLINT - len = strlen(start_dir) + strlen(name) + 6; - s = xmallocz(len); - - vim_snprintf(s, len, start_dir, suffix, name); - done |= do_in_path(p_pp, s, flags & ~DIP_AFTER, callback, cookie); - - xfree(s); + prefix = (flags & DIP_AFTER) ? "start/*/after/" : "start/*/"; // NOLINT + done |= do_in_path(p_pp, prefix, name, flags & ~DIP_AFTER, callback, cookie); } } if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_OPT)) { - char *opt_dir = "pack/*/opt/*/%s"; // NOLINT - size_t len = strlen(opt_dir) + strlen(name); - char *s = xmallocz(len); - - vim_snprintf(s, len, opt_dir, name); - done |= do_in_path(p_pp, s, flags, callback, cookie); - - xfree(s); + done |= do_in_path(p_pp, "pack/*/opt/*/", name, flags, callback, cookie); // NOLINT if (done == FAIL || (flags & DIP_ALL)) { - opt_dir = "opt/*/%s"; // NOLINT - len = strlen(opt_dir) + strlen(name); - s = xmallocz(len); - - vim_snprintf(s, len, opt_dir, name); - done |= do_in_path(p_pp, s, flags, callback, cookie); - - xfree(s); + done |= do_in_path(p_pp, "opt/*/", name, flags, callback, cookie); // NOLINT } } @@ -1173,7 +1154,7 @@ static bool add_opt_pack_plugins(int num_fnames, char **fnames, bool all, void * /// Add all packages in the "start" directory to 'runtimepath'. void add_pack_start_dirs(void) { - do_in_path(p_pp, NULL, DIP_ALL + DIP_DIR, add_pack_start_dir, NULL); + do_in_path(p_pp, "", NULL, DIP_ALL + DIP_DIR, add_pack_start_dir, NULL); } static bool pack_has_entries(char *buf) @@ -1215,9 +1196,9 @@ static bool add_pack_start_dir(int num_fnames, char **fnames, bool all, void *co void load_start_packages(void) { did_source_packages = true; - do_in_path(p_pp, "pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT + do_in_path(p_pp, "", "pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT add_start_pack_plugins, &APP_LOAD); - do_in_path(p_pp, "start/*", DIP_ALL + DIP_DIR, // NOLINT + do_in_path(p_pp, "", "start/*", DIP_ALL + DIP_DIR, // NOLINT add_start_pack_plugins, &APP_LOAD); } @@ -1283,7 +1264,8 @@ void ex_packadd(exarg_T *eap) // The first round don't give a "not found" error, in the second round // only when nothing was found in the first round. res = - do_in_path(p_pp, pat, DIP_ALL + DIP_DIR + (round == 2 && res == FAIL ? DIP_ERR : 0), + do_in_path(p_pp, "", pat, + DIP_ALL + DIP_DIR + (round == 2 && res == FAIL ? DIP_ERR : 0), round == 1 ? add_start_pack_plugins : add_opt_pack_plugins, eap->forceit ? &APP_ADD_DIR : &APP_BOTH); xfree(pat); -- cgit From 5970157e1d22fd5e05ae5d3bd949f807fb7a744c Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 17 May 2023 16:08:06 +0200 Subject: refactor(map): enhanced implementation, Clean Codeā„¢, etc etc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This involves two redesigns of the map.c implementations: 1. Change of macro style and code organization The old khash.h and map.c implementation used huge #define blocks with a lot of backslash line continuations. This instead uses the "implementation file" .c.h pattern. Such a file is meant to be included multiple times, with different macros set prior to inclusion as parameters. we already use this pattern e.g. for eval/typval_encode.c.h to implement different typval encoders reusing a similar structure. We can structure this code into two parts. one that only depends on key type and is enough to implement sets, and one which depends on both key and value to implement maps (as a wrapper around sets, with an added value[] array) 2. Separate the main hash buckets from the key / value arrays Change the hack buckets to only contain an index into separate key / value arrays This is a common pattern in modern, state of the art hashmap implementations. Even though this leads to one more allocated array, it is this often is a net reduction of memory consumption. Consider key+value consuming at least 12 bytes per pair. On average, we will have twice as many buckets per item. Thus old implementation: 2*12 = 24 bytes per item New implementation 1*12 + 2*4 = 20 bytes per item And the difference gets bigger with larger items. One might think we have pulled a fast one here, as wouldn't the average size of the new key/value arrays be 1.5 slots per items due to amortized grows? But remember, these arrays are fully dense, and thus the accessed memory, measured in _cache lines_, the unit which actually matters, will be the fully used memory but just rounded up to the nearest cache line boundary. This has some other interesting properties, such as an insert-only set/map will be fully ordered by insert only. Preserving this ordering in face of deletions is more tricky tho. As we currently don't use ordered maps, the "delete" operation maintains compactness of the item arrays in the simplest way by breaking the ordering. It would be possible to implement an order-preserving delete although at some cost, like allowing the items array to become non-dense until the next rehash. Finally, in face of these two major changes, all code used in khash.h has been integrated into map.c and friends. Given the heavy edits it makes no sense to "layer" the code into a vendored and a wrapper part. Rather, the layered cake follows the specialization depth: code shared for all maps, code specialized to a key type (and its equivalence relation), and finally code specialized to value+key type. --- src/nvim/runtime.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 992566b0fe..269c3805a1 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -731,7 +731,7 @@ static bool path_is_after(char *buf, size_t buflen) RuntimeSearchPath runtime_search_path_build(void) { kvec_t(String) pack_entries = KV_INITIAL_VALUE; - Map(String, handle_T) pack_used = MAP_INIT; + Map(String, int) pack_used = MAP_INIT; Set(String) rtp_used = SET_INIT; RuntimeSearchPath search_path = KV_INITIAL_VALUE; CharVec after_path = KV_INITIAL_VALUE; @@ -744,7 +744,7 @@ RuntimeSearchPath runtime_search_path_build(void) String the_entry = { .data = cur_entry, .size = strlen(buf) }; kv_push(pack_entries, the_entry); - map_put(String, handle_T)(&pack_used, the_entry, 0); + map_put(String, int)(&pack_used, the_entry, 0); } char *rtp_entry; @@ -761,7 +761,7 @@ RuntimeSearchPath runtime_search_path_build(void) // fact: &rtp entries can contain wild chars expand_rtp_entry(&search_path, &rtp_used, buf, false); - handle_T *h = map_ref(String, handle_T)(&pack_used, cstr_as_string(buf), NULL); + handle_T *h = map_ref(String, int)(&pack_used, cstr_as_string(buf), NULL); if (h) { (*h)++; expand_pack_entry(&search_path, &rtp_used, &after_path, buf, buflen); @@ -770,7 +770,7 @@ RuntimeSearchPath runtime_search_path_build(void) for (size_t i = 0; i < kv_size(pack_entries); i++) { String item = kv_A(pack_entries, i); - handle_T h = map_get(String, handle_T)(&pack_used, item); + handle_T h = map_get(String, int)(&pack_used, item); if (h == 0) { expand_pack_entry(&search_path, &rtp_used, &after_path, item.data, item.size); } -- cgit From f91cd31d7d9d70006e0000592637d5d997eab52c Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 27 Sep 2023 21:46:39 +0200 Subject: refactor(messages): fold msg_outtrans_attr into msg_outtrans problem: there are too many different functions in message.c solution: fold some of the functions into themselves --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 269c3805a1..4cb5925176 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2329,7 +2329,7 @@ void ex_scriptnames(exarg_T *eap) vim_snprintf(IObuff, IOSIZE, "%3d: %s", i, NameBuff); if (!message_filtered(IObuff)) { msg_putchar('\n'); - msg_outtrans(IObuff); + msg_outtrans(IObuff, 0); line_breakcheck(); } } -- cgit From bc13bc154aa574e0bb58a50f2e0ca4570efa57c3 Mon Sep 17 00:00:00 2001 From: bfredl Date: Fri, 29 Sep 2023 16:10:54 +0200 Subject: refactor(message): smsg_attr -> smsg --- src/nvim/runtime.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 4cb5925176..e6a04c899c 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -353,9 +353,9 @@ int do_in_path(const char *path, const char *prefix, char *name, int flags, if (p_verbose > 10 && name != NULL) { verbose_enter(); if (*prefix != NUL) { - smsg(_("Searching for \"%s\" under \"%s\" in \"%s\""), name, prefix, path); + smsg(0, _("Searching for \"%s\" under \"%s\" in \"%s\""), name, prefix, path); } else { - smsg(_("Searching for \"%s\" in \"%s\""), name, path); + smsg(0, _("Searching for \"%s\" in \"%s\""), name, path); } verbose_leave(); } @@ -396,7 +396,7 @@ int do_in_path(const char *path, const char *prefix, char *name, int flags, if (p_verbose > 10) { verbose_enter(); - smsg(_("Searching for \"%s\""), buf); + smsg(0, _("Searching for \"%s\""), buf); verbose_leave(); } @@ -418,7 +418,7 @@ int do_in_path(const char *path, const char *prefix, char *name, int flags, semsg(_(e_dirnotf), basepath, name); } else if (p_verbose > 1) { verbose_enter(); - smsg(_("not found in '%s': \"%s\""), basepath, name); + smsg(0, _("not found in '%s': \"%s\""), basepath, name); verbose_leave(); } } @@ -481,7 +481,7 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c if (p_verbose > 10 && name != NULL) { verbose_enter(); - smsg(_("Searching for \"%s\" in runtime path"), name); + smsg(0, _("Searching for \"%s\" in runtime path"), name); verbose_leave(); } @@ -520,7 +520,7 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c if (p_verbose > 10) { verbose_enter(); - smsg(_("Searching for \"%s\""), buf); + smsg(0, _("Searching for \"%s\""), buf); verbose_leave(); } @@ -540,7 +540,7 @@ int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *c semsg(_(e_dirnotf), "runtime path", name); } else if (p_verbose > 1) { verbose_enter(); - smsg(_("not found in runtime path: \"%s\""), name); + smsg(0, _("not found in runtime path: \"%s\""), name); verbose_leave(); } } @@ -2047,7 +2047,7 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) return retval; } if (os_isdir(fname_exp)) { - smsg(_("Cannot source a directory: \"%s\""), fname); + smsg(0, _("Cannot source a directory: \"%s\""), fname); goto theend; } @@ -2091,9 +2091,9 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) if (p_verbose > 1) { verbose_enter(); if (SOURCING_NAME == NULL) { - smsg(_("could not source \"%s\""), fname); + smsg(0, _("could not source \"%s\""), fname); } else { - smsg(_("line %" PRId64 ": could not source \"%s\""), + smsg(0, _("line %" PRId64 ": could not source \"%s\""), (int64_t)SOURCING_LNUM, fname); } verbose_leave(); @@ -2107,9 +2107,9 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) if (p_verbose > 1) { verbose_enter(); if (SOURCING_NAME == NULL) { - smsg(_("sourcing \"%s\""), fname); + smsg(0, _("sourcing \"%s\""), fname); } else { - smsg(_("line %" PRId64 ": sourcing \"%s\""), (int64_t)SOURCING_LNUM, fname); + smsg(0, _("line %" PRId64 ": sourcing \"%s\""), (int64_t)SOURCING_LNUM, fname); } verbose_leave(); } @@ -2242,9 +2242,9 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) estack_pop(); if (p_verbose > 1) { verbose_enter(); - smsg(_("finished sourcing %s"), fname); + smsg(0, _("finished sourcing %s"), fname); if (SOURCING_NAME != NULL) { - smsg(_("continuing in %s"), SOURCING_NAME); + smsg(0, _("continuing in %s"), SOURCING_NAME); } verbose_leave(); } -- cgit From cf8b2c0e74fd5e723b0c15c2ce84e6900fd322d3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 12:05:28 +0800 Subject: build(iwyu): add a few more _defs.h mappings (#25435) --- src/nvim/runtime.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index e6a04c899c..53896cb637 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -17,7 +18,6 @@ #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" -#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand.h" #include "nvim/debugger.h" @@ -31,6 +31,7 @@ #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" +#include "nvim/hashtab.h" #include "nvim/lua/executor.h" #include "nvim/macros.h" #include "nvim/map.h" -- cgit From dc6d0d2daf69e2fdadda81feb97906dbc962a239 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 14:41:34 +0800 Subject: refactor: reorganize option header files (#25437) - Move vimoption_T to option.h - option_defs.h is for option-related types - option_vars.h corresponds to Vim's option.h - option_defs.h and option_vars.h don't include each other --- src/nvim/runtime.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 53896cb637..12cf08636f 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -40,6 +40,8 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option.h" +#include "nvim/option_defs.h" +#include "nvim/option_vars.h" #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/stdpaths_defs.h" -- cgit From 09a17f91d0d362c6e58bfdbe3ccdeacffb0b44b9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 2 Oct 2023 10:45:33 +0800 Subject: refactor: move cmdline completion types to cmdexpand_defs.h (#25465) --- src/nvim/runtime.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 12cf08636f..360088758d 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -20,6 +20,7 @@ #include "nvim/autocmd.h" #include "nvim/charset.h" #include "nvim/cmdexpand.h" +#include "nvim/cmdexpand_defs.h" #include "nvim/debugger.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" -- cgit From 8e58d37f2e15ac8540377148e55ed08a039aadb6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 11 Nov 2023 11:20:08 +0100 Subject: refactor: remove redundant casts --- src/nvim/runtime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 360088758d..47bbe64c96 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2136,7 +2136,7 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) cookie.finished = false; // Check if this script has a breakpoint. - cookie.breakpoint = dbg_find_breakpoint(true, fname_exp, (linenr_T)0); + cookie.breakpoint = dbg_find_breakpoint(true, fname_exp, 0); cookie.fname = fname_exp; cookie.dbg_tick = debug_tick; @@ -2495,7 +2495,7 @@ void f_getscriptinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) continue; } - if (filterpat && !vim_regexec(®match, si->sn_name, (colnr_T)0)) { + if (filterpat && !vim_regexec(®match, si->sn_name, 0)) { continue; } -- cgit From 353a4be7e84fdc101318215bdcc8a7e780d737fe Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 12 Nov 2023 13:13:58 +0100 Subject: build: remove PVS We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable. --- src/nvim/runtime.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 47bbe64c96..1438385e66 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - /// @file runtime.c /// /// Management of runtime files (including packages) -- cgit From 28f4f3c48498086307ed825d1761edb5789ca0e8 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 12 Nov 2023 15:54:54 +0100 Subject: refactor: follow style guide - reduce variable scope - prefer initialization over declaration and assignment - use bool to represent boolean values --- src/nvim/runtime.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 1438385e66..83c4a68af2 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2583,10 +2583,8 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat) } if (line != NULL && sp->conv.vc_type != CONV_NONE) { - char *s; - // Convert the encoding of the script line. - s = string_convert(&sp->conv, line, NULL); + char *s = string_convert(&sp->conv, line, NULL); if (s != NULL) { xfree(line); line = s; -- cgit From ac1113ded5f8f09dd99a9894d7a7e795626fb728 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 13 Nov 2023 23:40:37 +0100 Subject: refactor: follow style guide - reduce variable scope - prefer initialization over declaration and assignment --- src/nvim/runtime.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 83c4a68af2..9b8bd90745 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -911,7 +911,6 @@ static int gen_expand_wildcards_and_cb(int num_pat, char **pats, int flags, bool static int add_pack_dir_to_rtp(char *fname, bool is_pack) { char *p; - char *buf = NULL; char *afterdir = NULL; int retval = FAIL; @@ -946,7 +945,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) // Find "ffname" in "p_rtp", ignoring '/' vs '\' differences // Also stop at the first "after" directory size_t fname_len = strlen(ffname); - buf = try_malloc(MAXPATHL); + char *buf = try_malloc(MAXPATHL); if (buf == NULL) { goto theend; } @@ -2029,8 +2028,6 @@ int do_source_str(const char *cmd, const char *traceback_name) int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) { struct source_cookie cookie; - char *p; - char *fname_exp; uint8_t *firstline = NULL; int retval = FAIL; int save_debug_break_level = debug_break_level; @@ -2038,11 +2035,11 @@ int do_source(char *fname, int check_other, int is_vimrc, int *ret_sid) proftime_T wait_start; bool trigger_source_post = false; - p = expand_env_save(fname); + char *p = expand_env_save(fname); if (p == NULL) { return retval; } - fname_exp = fix_fname(p); + char *fname_exp = fix_fname(p); xfree(p); if (fname_exp == NULL) { return retval; @@ -2746,8 +2743,6 @@ void ex_finish(exarg_T *eap) /// an extra do_cmdline(). "reanimate" is used in the latter case. void do_finish(exarg_T *eap, int reanimate) { - int idx; - if (reanimate) { ((struct source_cookie *)getline_cookie(eap->getline, eap->cookie))->finished = false; @@ -2757,7 +2752,7 @@ void do_finish(exarg_T *eap, int reanimate) // not in its finally clause (which then is to be executed next) is found. // In this case, make the ":finish" pending for execution at the ":endtry". // Otherwise, finish normally. - idx = cleanup_conditionals(eap->cstack, 0, true); + int idx = cleanup_conditionals(eap->cstack, 0, true); if (idx >= 0) { eap->cstack->cs_pending[idx] = CSTP_FINISH; report_make_pending(CSTP_FINISH, NULL); -- cgit From a6e3d93421ba13c407a96fac9cc01fa41ec7ad98 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 16 Nov 2023 10:59:11 +0100 Subject: refactor: enable formatting for ternaries This requires removing the "Inner expression should be aligned" rule from clint as it prevents essentially any formatting regarding ternary operators. --- src/nvim/runtime.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 9b8bd90745..08a5d936b3 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -152,8 +152,8 @@ char *estack_sfile(estack_arg_T which) ? &entry->es_info.ufunc->uf_script_ctx : &entry->es_info.aucmd->script_ctx); return def_ctx->sc_sid > 0 - ? xstrdup((SCRIPT_ITEM(def_ctx->sc_sid)->sn_name)) - : NULL; + ? xstrdup((SCRIPT_ITEM(def_ctx->sc_sid)->sn_name)) + : NULL; } else if (entry->es_type == ETYPE_SCRIPT) { return xstrdup(entry->es_name); } @@ -186,8 +186,8 @@ char *estack_sfile(estack_arg_T which) len += strlen(type_name); ga_grow(&ga, (int)len); linenr_T lnum = idx == exestack.ga_len - 1 - ? which == ESTACK_STACK ? SOURCING_LNUM : 0 - : entry->es_lnum; + ? which == ESTACK_STACK ? SOURCING_LNUM : 0 + : entry->es_lnum; char *dots = idx == exestack.ga_len - 1 ? "" : ".."; if (lnum == 0) { // For the bottom entry of : do not add the line number, @@ -1657,11 +1657,11 @@ char *runtimepath_default(bool clean_arg) { size_t rtp_size = 0; char *const data_home = clean_arg - ? NULL - : stdpaths_get_xdg_var(kXDGDataHome); + ? NULL + : stdpaths_get_xdg_var(kXDGDataHome); char *const config_home = clean_arg - ? NULL - : stdpaths_get_xdg_var(kXDGConfigHome); + ? NULL + : stdpaths_get_xdg_var(kXDGConfigHome); char *const vimruntime = vim_getenv("VIMRUNTIME"); char *const libdir = get_lib_dir(); char *const data_dirs = stdpaths_get_xdg_var(kXDGDataDirs); @@ -2415,8 +2415,8 @@ linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie) FUNC_ATTR_PURE { return fgetline == getsourceline - ? ((struct source_cookie *)cookie)->sourcing_lnum - : SOURCING_LNUM; + ? ((struct source_cookie *)cookie)->sourcing_lnum + : SOURCING_LNUM; } /// Return a List of script-local functions defined in the script with id "sid". -- cgit From 488038580934f301c1528a14548ec0cabd16c2cd Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 10 Nov 2023 14:06:04 +0100 Subject: build: adjust clang-tidy warning exclusion logic Enable all clang-tidy warnings by default instead of disabling them. This ensures that we don't miss useful warnings on each clang-tidy version upgrade. A drawback of this is that it will force us to either fix or adjust the warnings as soon as possible. --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 08a5d936b3..decf16c02e 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1640,7 +1640,7 @@ char *get_lib_dir(void) // Find library path relative to the nvim binary: ../lib/nvim/ char exe_name[MAXPATHL]; vim_get_prefix_from_exepath(exe_name); - if (append_path(exe_name, "lib" _PATHSEPSTR "nvim", MAXPATHL) == OK) { + if (append_path(exe_name, "lib/nvim", MAXPATHL) == OK) { return xstrdup(exe_name); } return NULL; -- cgit From 38a20dd89f91c45ec8589bf1c50d50732882d38a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 27 Nov 2023 20:58:37 +0800 Subject: build(IWYU): replace most private mappings with pragmas (#26247) --- src/nvim/runtime.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index decf16c02e..e6720a9211 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -40,6 +40,7 @@ #include "nvim/option.h" #include "nvim/option_defs.h" #include "nvim/option_vars.h" +#include "nvim/os/fs.h" #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/stdpaths_defs.h" -- cgit From 8b428ca8b79ebb7b36c3e403ff3bcb6924a635a6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 16:00:21 +0100 Subject: build(IWYU): fix includes for func_attr.h --- src/nvim/runtime.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index e6720a9211..dd560fd292 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -25,6 +25,7 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" +#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" -- cgit From ab7c0e9904610a1554af1c34a42bcaa25c847c15 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 19:47:06 +0100 Subject: refactor: create runtime_defs.h --- src/nvim/runtime.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index dd560fd292..491a281d5b 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -6,18 +6,19 @@ #include #include #include +#include #include #include #include #include +#include "klib/kvec.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" #include "nvim/charset.h" #include "nvim/cmdexpand.h" -#include "nvim/cmdexpand_defs.h" #include "nvim/debugger.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" @@ -46,10 +47,12 @@ #include "nvim/os/os.h" #include "nvim/os/stdpaths_defs.h" #include "nvim/path.h" +#include "nvim/pos_defs.h" #include "nvim/profile.h" #include "nvim/regexp.h" #include "nvim/runtime.h" #include "nvim/strings.h" +#include "nvim/types.h" #include "nvim/usercmd.h" #include "nvim/vim.h" -- cgit From 6c14ae6bfaf51415b555e9a6b85d1d280976358d Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 20:27:32 +0100 Subject: refactor: rename types.h to types_defs.h --- src/nvim/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 491a281d5b..30de776bff 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -52,7 +52,7 @@ #include "nvim/regexp.h" #include "nvim/runtime.h" #include "nvim/strings.h" -#include "nvim/types.h" +#include "nvim/types_defs.h" #include "nvim/usercmd.h" #include "nvim/vim.h" -- cgit From 718053b7a97c4e2fbaa6077d3c9f4dc7012c8aad Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 28 Nov 2023 07:47:36 +0800 Subject: refactor: fix runtime_defs.h (#26259) --- src/nvim/runtime.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 30de776bff..d5c076d914 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -76,6 +76,15 @@ struct source_cookie { vimconv_T conv; ///< type of conversion }; +typedef struct { + char *path; + bool after; + TriState has_lua; +} SearchPathItem; + +typedef kvec_t(SearchPathItem) RuntimeSearchPath; +typedef kvec_t(char *) CharVec; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "runtime.c.generated.h" #endif @@ -432,7 +441,7 @@ int do_in_path(const char *path, const char *prefix, char *name, int flags, return did_one ? OK : FAIL; } -RuntimeSearchPath runtime_search_path_get_cached(int *ref) +static RuntimeSearchPath runtime_search_path_get_cached(int *ref) FUNC_ATTR_NONNULL_ALL { runtime_search_path_validate(); @@ -447,7 +456,7 @@ RuntimeSearchPath runtime_search_path_get_cached(int *ref) return runtime_search_path; } -RuntimeSearchPath copy_runtime_search_path(const RuntimeSearchPath src) +static RuntimeSearchPath copy_runtime_search_path(const RuntimeSearchPath src) { RuntimeSearchPath dst = KV_INITIAL_VALUE; for (size_t j = 0; j < kv_size(src); j++) { @@ -458,7 +467,7 @@ RuntimeSearchPath copy_runtime_search_path(const RuntimeSearchPath src) return dst; } -void runtime_search_path_unref(RuntimeSearchPath path, const int *ref) +static void runtime_search_path_unref(RuntimeSearchPath path, const int *ref) FUNC_ATTR_NONNULL_ALL { if (*ref) { @@ -478,7 +487,7 @@ void runtime_search_path_unref(RuntimeSearchPath path, const int *ref) /// When "flags" has DIP_ERR: give an error message if there is no match. /// /// return FAIL when no file could be sourced, OK otherwise. -int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *cookie) +static int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, void *cookie) { char *tail; bool did_one = false; @@ -597,8 +606,8 @@ ArrayOf(String) runtime_get_named_thread(bool lua, Array pat, bool all) return rv; } -ArrayOf(String) runtime_get_named_common(bool lua, Array pat, bool all, - RuntimeSearchPath path, char *buf, size_t buf_len) +static ArrayOf(String) runtime_get_named_common(bool lua, Array pat, bool all, + RuntimeSearchPath path, char *buf, size_t buf_len) { ArrayOf(String) rv = ARRAY_DICT_INIT; for (size_t i = 0; i < kv_size(path); i++) { @@ -734,7 +743,7 @@ static bool path_is_after(char *buf, size_t buflen) && strcmp(buf + buflen - 5, "after") == 0; } -RuntimeSearchPath runtime_search_path_build(void) +static RuntimeSearchPath runtime_search_path_build(void) { kvec_t(String) pack_entries = KV_INITIAL_VALUE; Map(String, int) pack_used = MAP_INIT; @@ -809,7 +818,7 @@ const char *did_set_runtimepackpath(optset_T *args) return NULL; } -void runtime_search_path_free(RuntimeSearchPath path) +static void runtime_search_path_free(RuntimeSearchPath path) { for (size_t j = 0; j < kv_size(path); j++) { SearchPathItem item = kv_A(path, j); -- cgit From 79b6ff28ad1204fbb4199b9092f5c578d88cb28e Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 28 Nov 2023 20:31:00 +0100 Subject: refactor: fix headers with IWYU --- src/nvim/runtime.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index d5c076d914..a0926865e6 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -15,7 +15,7 @@ #include "klib/kvec.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/charset.h" #include "nvim/cmdexpand.h" @@ -33,8 +33,8 @@ #include "nvim/globals.h" #include "nvim/hashtab.h" #include "nvim/lua/executor.h" -#include "nvim/macros.h" -#include "nvim/map.h" +#include "nvim/macros_defs.h" +#include "nvim/map_defs.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" @@ -54,7 +54,7 @@ #include "nvim/strings.h" #include "nvim/types_defs.h" #include "nvim/usercmd.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" /// Structure used to store info for each sourced file. /// It is shared between do_source() and getsourceline(). -- cgit From a6cba103cebce535279db197f9efeb34e9d1171f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 29 Nov 2023 20:32:40 +0800 Subject: refactor: move some constants out of vim_defs.h (#26298) --- src/nvim/runtime.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/nvim/runtime.c') diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index a0926865e6..38d3942126 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -55,6 +55,9 @@ #include "nvim/types_defs.h" #include "nvim/usercmd.h" #include "nvim/vim_defs.h" +#ifdef USE_CRNL +# include "nvim/highlight.h" +#endif /// Structure used to store info for each sourced file. /// It is shared between do_source() and getsourceline(). @@ -65,7 +68,7 @@ struct source_cookie { char *nextline; ///< if not NULL: line that was read ahead linenr_T sourcing_lnum; ///< line number of the source file int finished; ///< ":finish" used -#if defined(USE_CRNL) +#ifdef USE_CRNL int fileformat; ///< EOL_UNKNOWN, EOL_UNIX or EOL_DOS bool error; ///< true if LF found after CR-LF #endif -- cgit