aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/private/helpers.c
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-09-24 10:57:09 +0800
committerGitHub <noreply@github.com>2023-09-24 10:57:09 +0800
commit4d3a38ac074fff7e2a4bede4cee7699bdd55ffdc (patch)
treeaba2143d3a3356e5721b511798a0f4f0d466bf03 /src/nvim/api/private/helpers.c
parent046c9a83f7ed2694c19d915a63ef0dfed9d29dc5 (diff)
downloadrneovim-4d3a38ac074fff7e2a4bede4cee7699bdd55ffdc.tar.gz
rneovim-4d3a38ac074fff7e2a4bede4cee7699bdd55ffdc.tar.bz2
rneovim-4d3a38ac074fff7e2a4bede4cee7699bdd55ffdc.zip
fix(api, lua): handle setting v: variables properly (#25325)
Diffstat (limited to 'src/nvim/api/private/helpers.c')
-rw-r--r--src/nvim/api/private/helpers.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 8fcabb3605..5463578b56 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -21,8 +21,10 @@
#include "nvim/buffer_defs.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
+#include "nvim/eval/vars.h"
#include "nvim/ex_eval.h"
#include "nvim/garray.h"
+#include "nvim/globals.h"
#include "nvim/highlight_group.h"
#include "nvim/lua/executor.h"
#include "nvim/map.h"
@@ -235,8 +237,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
// Delete the key
if (di == NULL) {
// Doesn't exist, fail
- api_set_error(err, kErrorTypeValidation, "Key not found: %s",
- key.data);
+ api_set_error(err, kErrorTypeValidation, "Key not found: %s", key.data);
} else {
// Notify watchers
if (watched) {
@@ -265,13 +266,23 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
di = tv_dict_item_alloc_len(key.data, key.size);
tv_dict_add(dict, di);
} else {
- if (watched) {
- tv_copy(&di->di_tv, &oldtv);
- }
// Return the old value
if (retval) {
rv = vim_to_object(&di->di_tv);
}
+ bool type_error = false;
+ if (dict == &vimvardict
+ && !before_set_vvar(key.data, di, &tv, true, watched, &type_error)) {
+ tv_clear(&tv);
+ if (type_error) {
+ api_set_error(err, kErrorTypeValidation,
+ "Setting v:%s to value with wrong type", key.data);
+ }
+ return rv;
+ }
+ if (watched) {
+ tv_copy(&di->di_tv, &oldtv);
+ }
tv_clear(&di->di_tv);
}