aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-02-23 00:59:11 +0300
committerZyX <kp-pav@yandex.ru>2017-02-23 19:48:41 +0300
commitd8a7e5fdbb7d94f06e30aedaea42028caec52c95 (patch)
tree9fd58ebc04c450f95dc9d6492b0f95ae18b047a8
parent9668d26a4384376d1eb052aa093d65c060359fef (diff)
downloadrneovim-d8a7e5fdbb7d94f06e30aedaea42028caec52c95.tar.gz
rneovim-d8a7e5fdbb7d94f06e30aedaea42028caec52c95.tar.bz2
rneovim-d8a7e5fdbb7d94f06e30aedaea42028caec52c95.zip
eval: Forbid (un)locking b:changedtick
Port of vim-patch:8.0.0343
-rw-r--r--runtime/doc/eval.txt7
-rw-r--r--src/nvim/eval.c6
-rw-r--r--test/functional/eval/changedtick_spec.lua12
3 files changed, 18 insertions, 7 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 1105601a0e..88ab502ab6 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -8606,9 +8606,12 @@ This does NOT work: >
:lockvar v
:let v = 'asdf' " fails!
:unlet v
-< *E741*
+< *E741* *E940*
If you try to change a locked variable you get an
- error message: "E741: Value is locked: {name}"
+ error message: "E741: Value is locked: {name}".
+ If you try to lock or unlock a built-in variable you
+ will get an error message "E940: Cannot lock or unlock
+ variable {name}".
[depth] is relevant when locking a |List| or
|Dictionary|. It specifies how deep the locking goes:
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index da084d8ecc..25ac0e2ad1 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -3091,6 +3091,12 @@ static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock)
true);
if (di == NULL) {
ret = FAIL;
+ } else if ((di->di_flags & DI_FLAGS_FIX)
+ && di->di_tv.v_type != VAR_DICT
+ && di->di_tv.v_type != VAR_LIST) {
+ // For historical reasons this error is not given for Lists and
+ // Dictionaries. E.g. b: dictionary may be locked/unlocked.
+ emsgf(_("E940: Cannot lock or unlock variable %s"), lp->ll_name);
} else {
if ((di->di_flags & (DI_FLAGS_LOCK|DI_FLAGS_FIX))
== (DI_FLAGS_LOCK|DI_FLAGS_FIX)) {
diff --git a/test/functional/eval/changedtick_spec.lua b/test/functional/eval/changedtick_spec.lua
index 83b07e6722..74e581bd3c 100644
--- a/test/functional/eval/changedtick_spec.lua
+++ b/test/functional/eval/changedtick_spec.lua
@@ -101,19 +101,21 @@ describe('b:changedtick', function()
redir_exec(':let b:'))
end)
it('fails to unlock b:changedtick', function()
- -- Note:
- -- - unlocking VAR_FIXED variables is not an error.
- -- - neither VAR_FIXED variables are reported as locked by islocked().
- -- So test mostly checks that b:changedtick status does not change.
eq(0, exc_exec('let d = b:'))
eq(0, funcs.islocked('b:changedtick'))
eq(0, funcs.islocked('d.changedtick'))
- eq('',
+ eq('\nE940: Cannot lock or unlock variable b:changedtick',
redir_exec('unlockvar b:changedtick'))
eq('\nE46: Cannot change read-only variable "d.changedtick"',
redir_exec('unlockvar d.changedtick'))
eq(0, funcs.islocked('b:changedtick'))
eq(0, funcs.islocked('d.changedtick'))
+ eq('\nE940: Cannot lock or unlock variable b:changedtick',
+ redir_exec('lockvar b:changedtick'))
+ eq('\nE46: Cannot change read-only variable "d.changedtick"',
+ redir_exec('lockvar d.changedtick'))
+ eq(0, funcs.islocked('b:changedtick'))
+ eq(0, funcs.islocked('d.changedtick'))
end)
it('is being completed', function()
feed(':echo b:<Tab><Home>let cmdline="<End>"<CR>')