diff options
author | ZyX <kp-pav@yandex.ru> | 2017-02-20 22:04:20 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2017-02-23 19:46:44 +0300 |
commit | f2c9fd312c49199bf2a052419c3cc10f4e513127 (patch) | |
tree | 948821579b0cbf5c2e541cb56c041c019ab95299 | |
parent | 908e53d98d580a74e7976b87ced17e1b865e4276 (diff) | |
download | rneovim-f2c9fd312c49199bf2a052419c3cc10f4e513127.tar.gz rneovim-f2c9fd312c49199bf2a052419c3cc10f4e513127.tar.bz2 rneovim-f2c9fd312c49199bf2a052419c3cc10f4e513127.zip |
eval: Make sure that b:changedtick may not be unlocked via :unlo b:var
It still may be unlocked by `:unlock b:.var`.
-rw-r--r-- | src/nvim/eval.c | 28 | ||||
-rw-r--r-- | src/nvim/globals.h | 2 | ||||
-rw-r--r-- | test/functional/eval/changedtick_spec.lua | 11 |
3 files changed, 28 insertions, 13 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4194f5fd7c..d9bf475e35 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -170,6 +170,8 @@ static char *e_letwrong = N_("E734: Wrong variable type for %s="); static char *e_nofunc = N_("E130: Unknown function: %s"); static char *e_illvar = N_("E461: Illegal variable name: %s"); static char *e_float_as_string = N_("E806: using Float as a String"); +static const char *e_readonlyvar = N_( + "E46: Cannot change read-only variable \"%.*s\""); static char_u * const empty_string = (char_u *)""; static char_u * const namespace_char = (char_u *)"abglstvw"; @@ -3057,29 +3059,33 @@ int do_unlet(char_u *name, int forceit) static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock) { int ret = OK; - int cc; - dictitem_T *di; - if (deep == 0) /* nothing to do */ + if (deep == 0) { // Nothing to do. return OK; + } if (lp->ll_tv == NULL) { - cc = *name_end; - *name_end = NUL; - // Normal name or expanded name. - di = find_var((const char *)lp->ll_name, STRLEN(lp->ll_name), NULL, true); + const size_t name_len = (size_t)(name_end - lp->ll_name); + dictitem_T *const di = find_var( + (const char *)lp->ll_name, name_len, NULL, + true); if (di == NULL) { ret = FAIL; } else { - if (lock) { + if ((di->di_flags & (DI_FLAGS_LOCK|DI_FLAGS_FIX)) + == (DI_FLAGS_LOCK|DI_FLAGS_FIX)) { + // Locked and fixed: do not alter lock, but issue an error. + // Provides compatibility with former `unlockvar b:changedtick` + // behaviour. + emsgf(_(e_readonlyvar), (int)name_len, lp->ll_name); + } else if (lock) { di->di_flags |= DI_FLAGS_LOCK; } else { di->di_flags &= ~DI_FLAGS_LOCK; } item_lock(&di->di_tv, deep, lock); } - *name_end = cc; } else if (lp->ll_range) { listitem_T *li = lp->ll_li; @@ -20542,7 +20548,9 @@ set_var ( static bool var_check_ro(int flags, char_u *name, bool use_gettext) { if (flags & DI_FLAGS_RO) { - EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name); + const char_u *const name_translated = ( + use_gettext ? (char_u *)_(name) : name); + emsgf(_(e_readonlyvar), (int)STRLEN(name_translated), name_translated); return true; } if ((flags & DI_FLAGS_RO_SBX) && sandbox) { diff --git a/src/nvim/globals.h b/src/nvim/globals.h index b141d40aa2..5a73af748f 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1173,8 +1173,6 @@ EXTERN char_u e_re_damg[] INIT(= N_("E43: Damaged match string")); EXTERN char_u e_re_corr[] INIT(= N_("E44: Corrupted regexp program")); EXTERN char_u e_readonly[] INIT(= N_( "E45: 'readonly' option is set (add ! to override)")); -EXTERN char_u e_readonlyvar[] INIT(= N_( - "E46: Cannot change read-only variable \"%s\"")); EXTERN char_u e_readonlysbx[] INIT(= N_( "E794: Cannot set variable in the sandbox: \"%s\"")); EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile")); diff --git a/test/functional/eval/changedtick_spec.lua b/test/functional/eval/changedtick_spec.lua index cf8297296f..f1ed95dd16 100644 --- a/test/functional/eval/changedtick_spec.lua +++ b/test/functional/eval/changedtick_spec.lua @@ -95,8 +95,17 @@ describe('b:changedtick', function() redir_exec(':let b:')) end) it('fails to unlock b:changedtick', function() + eq(0, exc_exec('let d = b:')) + eq(1, funcs.islocked('b:changedtick')) + -- FIXME + -- eq(1, funcs.islocked('d.changedtick')) + eq('\nE46: Cannot change read-only variable "b:changedtick"', + redir_exec('unlockvar b:changedtick')) -- FIXME - -- eq('\nE', redir_exec('unlockvar b:changedtick')) + -- eq('\nE46: Cannot change read-only variable "b:changedtick"', + -- redir_exec('unlockvar d.changedtick')) + eq(1, funcs.islocked('b:changedtick')) + -- eq(1, funcs.islocked('d.changedtick')) end) it('is being completed', function() feed(':echo b:<Tab><Home>let cmdline="<End>"<CR>') |