mirror of
https://github.com/neovim/neovim.git
synced 2025-09-18 09:18:19 +00:00
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.
7ebcba61b2
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -109,15 +109,7 @@ static hashtab_T compat_hashtab;
|
||||
/// Used for checking if local variables or arguments used in a lambda.
|
||||
bool *eval_lavars_used = NULL;
|
||||
|
||||
/// Array to hold the hashtab with variables local to each sourced script.
|
||||
/// Each item holds a variable (nameless) that points to the dict_T.
|
||||
typedef struct {
|
||||
ScopeDictDictItem sv_var;
|
||||
dict_T sv_dict;
|
||||
} scriptvar_T;
|
||||
|
||||
static garray_T ga_scripts = { 0, 0, sizeof(scriptvar_T *), 4, NULL };
|
||||
#define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1])
|
||||
#define SCRIPT_SV(id) (SCRIPT_ITEM(id).sn_vars)
|
||||
#define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
|
||||
|
||||
static int echo_attr = 0; // attributes used for ":echo"
|
||||
@@ -473,7 +465,7 @@ void eval_init(void)
|
||||
}
|
||||
|
||||
#if defined(EXITFREE)
|
||||
void eval_clear(void)
|
||||
static void evalvars_clear(void)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(vimvars); i++) {
|
||||
struct vimvar *p = &vimvars[i];
|
||||
@@ -488,28 +480,29 @@ void eval_clear(void)
|
||||
hash_init(&vimvarht); // garbage_collect() will access it
|
||||
hash_clear(&compat_hashtab);
|
||||
|
||||
free_scriptnames();
|
||||
// global variables
|
||||
vars_clear(&globvarht);
|
||||
|
||||
// Script-local variables. Clear all the variables here.
|
||||
// The scriptvar_T is cleared later in free_scriptnames(), because a
|
||||
// variable in one script might hold a reference to the whole scope of
|
||||
// another script.
|
||||
for (int i = 1; i <= script_items.ga_len; i++) {
|
||||
vars_clear(&SCRIPT_VARS(i));
|
||||
}
|
||||
}
|
||||
|
||||
void eval_clear(void)
|
||||
{
|
||||
evalvars_clear();
|
||||
free_scriptnames(); // must come after evalvars_clear().
|
||||
# ifdef HAVE_WORKING_LIBINTL
|
||||
free_locales();
|
||||
# endif
|
||||
|
||||
// global variables
|
||||
vars_clear(&globvarht);
|
||||
|
||||
// autoloaded script names
|
||||
ga_clear_strings(&ga_loaded);
|
||||
|
||||
// Script-local variables. First clear all the variables and in a second
|
||||
// loop free the scriptvar_T, because a variable in one script might hold
|
||||
// a reference to the whole scope of another script.
|
||||
for (int i = 1; i <= ga_scripts.ga_len; i++) {
|
||||
vars_clear(&SCRIPT_VARS(i));
|
||||
}
|
||||
for (int i = 1; i <= ga_scripts.ga_len; i++) {
|
||||
xfree(SCRIPT_SV(i));
|
||||
}
|
||||
ga_clear(&ga_scripts);
|
||||
|
||||
// unreferenced lists and dicts
|
||||
(void)garbage_collect(false);
|
||||
|
||||
@@ -970,7 +963,7 @@ void list_vim_vars(int *first)
|
||||
/// List script-local variables, if there is a script.
|
||||
void list_script_vars(int *first)
|
||||
{
|
||||
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= ga_scripts.ga_len) {
|
||||
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len) {
|
||||
list_hashtable_vars(&SCRIPT_VARS(current_sctx.sc_sid), "s:", false, first);
|
||||
}
|
||||
}
|
||||
@@ -4116,7 +4109,7 @@ bool garbage_collect(bool testing)
|
||||
ABORTING(set_ref_in_previous_funccal)(copyID);
|
||||
|
||||
// script-local variables
|
||||
for (int i = 1; i <= ga_scripts.ga_len; i++) {
|
||||
for (int i = 1; i <= script_items.ga_len; i++) {
|
||||
ABORTING(set_ref_in_ht)(&SCRIPT_VARS(i), copyID, NULL);
|
||||
}
|
||||
|
||||
@@ -7131,7 +7124,7 @@ hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, const char
|
||||
} else if (*name == 's' // script variable
|
||||
&& (current_sctx.sc_sid > 0 || current_sctx.sc_sid == SID_STR
|
||||
|| current_sctx.sc_sid == SID_LUA)
|
||||
&& current_sctx.sc_sid <= ga_scripts.ga_len) {
|
||||
&& current_sctx.sc_sid <= script_items.ga_len) {
|
||||
// For anonymous scripts without a script item, create one now so script vars can be used
|
||||
if (current_sctx.sc_sid == SID_LUA) {
|
||||
// try to resolve lua filename & line no so it can be shown in lastset messages.
|
||||
@@ -7182,27 +7175,9 @@ hashtab_T *find_var_ht(const char *name, const size_t name_len, const char **var
|
||||
/// sourcing this script and when executing functions defined in the script.
|
||||
void new_script_vars(scid_T id)
|
||||
{
|
||||
scriptvar_T *sv;
|
||||
|
||||
ga_grow(&ga_scripts, id - ga_scripts.ga_len);
|
||||
|
||||
// Re-allocating ga_data means that an ht_array pointing to
|
||||
// ht_smallarray becomes invalid. We can recognize this: ht_mask is
|
||||
// at its init value. Also reset "v_dict", it's always the same.
|
||||
for (int i = 1; i <= ga_scripts.ga_len; i++) {
|
||||
hashtab_T *ht = &SCRIPT_VARS(i);
|
||||
if (ht->ht_mask == HT_INIT_SIZE - 1) {
|
||||
ht->ht_array = ht->ht_smallarray;
|
||||
}
|
||||
sv = SCRIPT_SV(i);
|
||||
sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict;
|
||||
}
|
||||
|
||||
while (ga_scripts.ga_len < id) {
|
||||
sv = SCRIPT_SV(ga_scripts.ga_len + 1) = xcalloc(1, sizeof(scriptvar_T));
|
||||
init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
|
||||
ga_scripts.ga_len++;
|
||||
}
|
||||
scriptvar_T *sv = xcalloc(1, sizeof(scriptvar_T));
|
||||
init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
|
||||
SCRIPT_ITEM(id).sn_vars = sv;
|
||||
}
|
||||
|
||||
/// Initialize dictionary "dict" as a scope and set variable "dict_var" to
|
||||
|
Reference in New Issue
Block a user