CheckDefExecFailure(lines, 'E171:', 1)
enddef
+let s:theList = [1, 2, 3]
+
+def Test_lockvar()
+ s:theList[1] = 22
+ assert_equal([1, 22, 3], s:theList)
+ lockvar s:theList
+ assert_fails('theList[1] = 77', 'E741:')
+ unlockvar s:theList
+ s:theList[1] = 44
+ assert_equal([1, 44, 3], s:theList)
+
+ var lines =<< trim END
+ vim9script
+ var theList = [1, 2, 3]
+ def SetList()
+ theList[1] = 22
+ assert_equal([1, 22, 3], theList)
+ lockvar theList
+ theList[1] = 77
+ enddef
+ SetList()
+ END
+ CheckScriptFailure(lines, 'E1119', 4)
+
+ lines =<< trim END
+ var theList = [1, 2, 3]
+ lockvar theList
+ END
+ CheckDefFailure(lines, 'E1178', 2)
+
+ lines =<< trim END
+ var theList = [1, 2, 3]
+ unlockvar theList
+ END
+ CheckDefFailure(lines, 'E1178', 2)
+enddef
+
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
}
/*
- * compile "unlet var", "lock var" and "unlock var"
- * "arg" points to "var".
+ * Callback passed to ex_unletlock().
*/
- static char_u *
-compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
+ static int
+compile_lock_unlock(
+ lval_T *lvp,
+ char_u *name_end,
+ exarg_T *eap,
+ int deep UNUSED,
+ void *coookie)
{
- char_u *p = arg;
+ cctx_T *cctx = coookie;
+ int cc = *name_end;
+ char_u *p = lvp->ll_name;
+ int ret = OK;
+ size_t len;
+ char_u *buf;
- if (eap->cmdidx != CMD_unlet)
+ if (cctx->ctx_skip == SKIP_YES)
+ return OK;
+
+ // Cannot use :lockvar and :unlockvar on local variables.
+ if (p[1] != ':')
{
- emsg("Sorry, :lock and unlock not implemented yet");
- return NULL;
+ char_u *end = skip_var_one(p, FALSE);
+
+ if (lookup_local(p, end - p, NULL, cctx) == OK)
+ {
+ emsg(_(e_cannot_lock_unlock_local_variable));
+ return FAIL;
+ }
}
- ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD | GLV_COMPILING,
- compile_unlet, cctx);
+ // Checking is done at runtime.
+ *name_end = NUL;
+ len = name_end - p + 20;
+ buf = alloc(len);
+ if (buf == NULL)
+ ret = FAIL;
+ else
+ {
+ vim_snprintf((char *)buf, len, "%s %s",
+ eap->cmdidx == CMD_lockvar ? "lockvar" : "unlockvar",
+ p);
+ ret = generate_EXEC(cctx, buf);
+
+ vim_free(buf);
+ *name_end = cc;
+ }
+ return ret;
+}
+
+/*
+ * compile "unlet var", "lock var" and "unlock var"
+ * "arg" points to "var".
+ */
+ static char_u *
+compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
+{
+ ex_unletlock(eap, arg, 0, GLV_NO_AUTOLOAD | GLV_COMPILING,
+ eap->cmdidx == CMD_unlet ? compile_unlet : compile_lock_unlock,
+ cctx);
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
}