patch 8.2.0601: Vim9: :unlet is not compiled
Problem: Vim9: :unlet is not compiled.
Solution: Implement :unlet instruction and check for errors.
diff --git a/src/evalvars.c b/src/evalvars.c
index 5dddd09..1952eb8 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -172,9 +172,8 @@
static void list_tab_vars(int *first);
static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first);
static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int flags, char_u *endchars, char_u *op);
-static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep);
-static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit);
-static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock);
+static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep, void *cookie);
+static int do_lock_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep, void *cookie);
static void item_lock(typval_T *tv, int deep, int lock);
static void delete_var(hashtab_T *ht, hashitem_T *hi);
static void list_one_var(dictitem_T *v, char *prefix, int *first);
@@ -1372,7 +1371,7 @@
void
ex_unlet(exarg_T *eap)
{
- ex_unletlock(eap, eap->arg, 0);
+ ex_unletlock(eap, eap->arg, 0, 0, do_unlet_var, NULL);
}
/*
@@ -1392,17 +1391,22 @@
arg = skipwhite(arg);
}
- ex_unletlock(eap, arg, deep);
+ ex_unletlock(eap, arg, deep, 0, do_lock_var, NULL);
}
/*
* ":unlet", ":lockvar" and ":unlockvar" are quite similar.
+ * Also used for Vim9 script. "callback" is invoked as:
+ * callback(&lv, name_end, eap, deep, cookie)
*/
- static void
+ void
ex_unletlock(
exarg_T *eap,
char_u *argstart,
- int deep)
+ int deep,
+ int glv_flags,
+ int (*callback)(lval_T *, char_u *, exarg_T *, int, void *),
+ void *cookie)
{
char_u *arg = argstart;
char_u *name_end;
@@ -1426,8 +1430,8 @@
}
// Parse the name and find the end.
- name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0,
- FNE_CHECK_START);
+ name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error,
+ glv_flags, FNE_CHECK_START);
if (lv.ll_name == NULL)
error = TRUE; // error but continue parsing
if (name_end == NULL || (!VIM_ISWHITE(*name_end)
@@ -1443,26 +1447,15 @@
break;
}
- if (!error && !eap->skip)
- {
- if (eap->cmdidx == CMD_unlet)
- {
- if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL)
- error = TRUE;
- }
- else
- {
- if (do_lock_var(&lv, name_end, deep,
- eap->cmdidx == CMD_lockvar) == FAIL)
- error = TRUE;
- }
- }
+ if (!error && !eap->skip
+ && callback(&lv, name_end, eap, deep, cookie) == FAIL)
+ error = TRUE;
if (!eap->skip)
clear_lval(&lv);
arg = skipwhite(name_end);
- } while (!ends_excmd(*arg));
+ } while (!ends_excmd2(name_end, arg));
eap->nextcmd = check_nextcmd(arg);
}
@@ -1471,8 +1464,11 @@
do_unlet_var(
lval_T *lp,
char_u *name_end,
- int forceit)
+ exarg_T *eap,
+ int deep UNUSED,
+ void *cookie UNUSED)
{
+ int forceit = eap->forceit;
int ret = OK;
int cc;
@@ -1541,6 +1537,10 @@
dict_T *d;
dictitem_T *di;
+ if (current_sctx.sc_version == SCRIPT_VERSION_VIM9
+ && check_vim9_unlet(name) == FAIL)
+ return FAIL;
+
ht = find_var_ht(name, &varname);
if (ht != NULL && *varname != NUL)
{
@@ -1592,9 +1592,11 @@
do_lock_var(
lval_T *lp,
char_u *name_end,
+ exarg_T *eap,
int deep,
- int lock)
+ void *cookie UNUSED)
{
+ int lock = eap->cmdidx == CMD_lockvar;
int ret = OK;
int cc;
dictitem_T *di;