summaryrefslogtreecommitdiffstats
path: root/src/scriptfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scriptfile.c')
-rw-r--r--src/scriptfile.c60
1 files changed, 42 insertions, 18 deletions
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 3faed4a700..ae46e7a86d 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -23,7 +23,7 @@ static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
static int last_current_SID_seq = 0;
#endif
-static int do_source_ext(char_u *fname, int check_other, int is_vimrc, int *ret_sid, exarg_T *eap);
+static int do_source_ext(char_u *fname, int check_other, int is_vimrc, int *ret_sid, exarg_T *eap, int clearvars);
/*
* Initialize the execution stack.
@@ -1084,6 +1084,20 @@ ExpandPackAddDir(
static void
cmd_source(char_u *fname, exarg_T *eap)
{
+ int clearvars = FALSE;
+
+ if (*fname != NUL && STRNCMP(fname, "++clear", 7) == 0)
+ {
+ // ++clear argument is supplied
+ clearvars = TRUE;
+ fname = fname + 7;
+ if (*fname != NUL)
+ {
+ semsg(_(e_invalid_argument_str), eap->arg);
+ return;
+ }
+ }
+
if (*fname != NUL && eap != NULL && eap->addr_count > 0)
{
// if a filename is specified to :source, then a range is not allowed
@@ -1098,7 +1112,7 @@ cmd_source(char_u *fname, exarg_T *eap)
emsg(_(e_argument_required));
else
// source ex commands from the current buffer
- do_source_ext(NULL, FALSE, FALSE, NULL, eap);
+ do_source_ext(NULL, FALSE, FALSE, NULL, eap, clearvars);
}
else if (eap != NULL && eap->forceit)
// ":source!": read Normal mode commands
@@ -1292,6 +1306,10 @@ errret:
* The 'eap' argument is used when sourcing lines from a buffer instead of a
* file.
*
+ * If 'clearvars' is TRUE, then for scripts which are loaded more than
+ * once, clear all the functions and variables previously defined in that
+ * script.
+ *
* This function may be called recursively!
*
* Return FAIL if file could not be opened, OK otherwise.
@@ -1303,7 +1321,8 @@ do_source_ext(
int check_other, // check for .vimrc and _vimrc
int is_vimrc, // DOSO_ value
int *ret_sid UNUSED,
- exarg_T *eap)
+ exarg_T *eap,
+ int clearvars UNUSED)
{
source_cookie_T cookie;
char_u *p;
@@ -1527,20 +1546,25 @@ do_source_ext(
{
si->sn_state = SN_STATE_RELOAD;
- // Script-local variables remain but "const" can be set again.
- // In Vim9 script variables will be cleared when "vim9script" is
- // encountered without the "noclear" argument.
- ht = &SCRIPT_VARS(sid);
- todo = (int)ht->ht_used;
- for (hi = ht->ht_array; todo > 0; ++hi)
- if (!HASHITEM_EMPTY(hi))
- {
- --todo;
- di = HI2DI(hi);
- di->di_flags |= DI_FLAGS_RELOAD;
- }
- // imports can be redefined once
- mark_imports_for_reload(sid);
+ if (!clearvars)
+ {
+ // Script-local variables remain but "const" can be set again.
+ // In Vim9 script variables will be cleared when "vim9script"
+ // is encountered without the "noclear" argument.
+ ht = &SCRIPT_VARS(sid);
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi)
+ if (!HASHITEM_EMPTY(hi))
+ {
+ --todo;
+ di = HI2DI(hi);
+ di->di_flags |= DI_FLAGS_RELOAD;
+ }
+ // imports can be redefined once
+ mark_imports_for_reload(sid);
+ }
+ else
+ clear_vim9_scriptlocal_vars(sid);
// reset version, "vim9script" may have been added or removed.
si->sn_version = 1;
@@ -1731,7 +1755,7 @@ do_source(
int is_vimrc, // DOSO_ value
int *ret_sid UNUSED)
{
- return do_source_ext(fname, check_other, is_vimrc, ret_sid, NULL);
+ return do_source_ext(fname, check_other, is_vimrc, ret_sid, NULL, FALSE);
}