diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-04-15 21:27:30 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-15 21:27:30 +0800 |
commit | 2e2101cf7b0e4a70f5670d9d1317860a47bb8385 (patch) | |
tree | dadcd914c45ee440bb85e63e889d9e2723182fdb /src | |
parent | eb151a9730f0000ff46e0b3467e29bb9f02ae362 (diff) | |
parent | 9770dcf96d77d734e2b88fc693c0f4fa0a17ef74 (diff) | |
download | rneovim-2e2101cf7b0e4a70f5670d9d1317860a47bb8385.tar.gz rneovim-2e2101cf7b0e4a70f5670d9d1317860a47bb8385.tar.bz2 rneovim-2e2101cf7b0e4a70f5670d9d1317860a47bb8385.zip |
Merge pull request #23107 from zeertzjq/vim-9.0.0269
vim-patch:9.0.{0269,0303,1431}: more getscriptinfo() features
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.lua | 2 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.c | 11 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.h | 6 | ||||
-rw-r--r-- | src/nvim/runtime.c | 76 |
4 files changed, 84 insertions, 11 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 66032adbaf..7dbfac80f3 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -189,7 +189,7 @@ return { gettabinfo={args={0, 1}, base=1}, gettabvar={args={2, 3}, base=1}, gettabwinvar={args={3, 4}, base=1}, - getscriptinfo={}, + getscriptinfo={args={0, 1}}, gettagstack={args={0, 1}, base=1}, gettext={args=1, base=1}, getwininfo={args={0, 1}, base=1}, diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 67b1e53a35..9705bc93db 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -2015,12 +2015,11 @@ static void list_functions(regmatch_T *regmatch) if (!HASHITEM_EMPTY(hi)) { ufunc_T *fp = HI2UF(hi); todo--; - if ((fp->uf_flags & FC_DEAD) == 0 - && (regmatch == NULL - ? (!message_filtered(fp->uf_name) - && !func_name_refcount(fp->uf_name)) - : (!isdigit((uint8_t)(*fp->uf_name)) - && vim_regexec(regmatch, fp->uf_name, 0)))) { + if (regmatch == NULL + ? (!message_filtered(fp->uf_name) + && !func_name_refcount(fp->uf_name)) + : (!isdigit((uint8_t)(*fp->uf_name)) + && vim_regexec(regmatch, fp->uf_name, 0))) { list_func_head(fp, false, false); if (changed != func_hashtab.ht_changed) { emsg(_("E454: function list was modified")); diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h index f0e1f5dca0..d0ad53c43d 100644 --- a/src/nvim/eval/userfunc.h +++ b/src/nvim/eval/userfunc.h @@ -28,10 +28,10 @@ struct funccal_entry; #define FC_DELETED 0x10 // :delfunction used while uf_refcount > 0 #define FC_REMOVED 0x20 // function redefined while uf_refcount > 0 #define FC_SANDBOX 0x40 // function defined in the sandbox -#define FC_DEAD 0x80 // function kept only for reference to dfunc -#define FC_EXPORT 0x100 // "export def Func()" +// #define FC_DEAD 0x80 // function kept only for reference to dfunc +// #define FC_EXPORT 0x100 // "export def Func()" #define FC_NOARGS 0x200 // no a: variables in lambda -#define FC_VIM9 0x400 // defined in vim9 script file +// #define FC_VIM9 0x400 // defined in vim9 script file #define FC_LUAREF 0x800 // luaref callback /// Structure used by trans_function_name() diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 1e39b58543..d091636e77 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" @@ -43,6 +44,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" @@ -2356,27 +2358,99 @@ 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 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); + } + }); + + return l; +} + /// "getscriptinfo()" function 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; - for (int i = 1; i <= script_items.ga_len; i++) { + regmatch_T regmatch = { + .regprog = NULL, + .rm_ic = p_ic, + }; + bool filterpat = false; + varnumber_T sid = -1; + + char *pat = NULL; + if (argvars[0].v_type == VAR_DICT) { + 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); + } + if (regmatch.regprog != NULL) { + filterpat = true; + } + } + } + + 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) { continue; } + if (filterpat && !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); + + // 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)); + } } + + vim_regfree(regmatch.regprog); + xfree(pat); } /// Get one full line from a sourced file. |