aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsmolck <46855713+smolck@users.noreply.github.com>2021-08-14 12:19:05 -0500
committerbfredl <bjorn.linse@gmail.com>2022-09-27 14:47:53 +0200
commitc7d30c152d1639523d05154e245ea60ed9a51a2b (patch)
tree9e329b4448ef83620d46160741791a6b3c4da86c /src
parent1d337d4e2f2265b13ecf19a3bc17ad302d3b0d96 (diff)
downloadrneovim-c7d30c152d1639523d05154e245ea60ed9a51a2b.tar.gz
rneovim-c7d30c152d1639523d05154e245ea60ed9a51a2b.tar.bz2
rneovim-c7d30c152d1639523d05154e245ea60ed9a51a2b.zip
fix(api): notify dict watchers on nvim_set_var and vim.g setter
Co-authored-by: bfredl <bjorn.linse@gmail.com> Co-authored-by: Christian Clason <c.clason@uni-graz.at>
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/private/helpers.c18
-rw-r--r--src/nvim/eval/typval.c2
-rw-r--r--src/nvim/eval/vars.c8
-rw-r--r--src/nvim/lua/stdlib.c19
4 files changed, 40 insertions, 7 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index b888d09343..73b5489d5c 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -218,6 +218,8 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
return rv;
}
+ bool watched = tv_dict_is_watched(dict);
+
if (del) {
// Delete the key
if (di == NULL) {
@@ -225,6 +227,10 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
api_set_error(err, kErrorTypeValidation, "Key not found: %s",
key.data);
} else {
+ // Notify watchers
+ if (watched) {
+ tv_dict_watcher_notify(dict, key.data, NULL, &di->di_tv);
+ }
// Return the old value
if (retval) {
rv = vim_to_object(&di->di_tv);
@@ -241,11 +247,16 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
return rv;
}
+ typval_T oldtv = TV_INITIAL_VALUE;
+
if (di == NULL) {
// Need to create an entry
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);
@@ -255,6 +266,13 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
// Update the value
tv_copy(&tv, &di->di_tv);
+
+ // Notify watchers
+ if (watched) {
+ tv_dict_watcher_notify(dict, key.data, &tv, &oldtv);
+ tv_clear(&oldtv);
+ }
+
// Clear the temporary variable
tv_clear(&tv);
}
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index f9aed7a966..5639414dad 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1781,7 +1781,7 @@ void tv_dict_watcher_notify(dict_T *const dict, const char *const key, typval_T
tv_dict_add(argv[2].vval.v_dict, v);
}
- if (oldtv) {
+ if (oldtv && oldtv->v_type != VAR_UNKNOWN) {
dictitem_T *const v = tv_dict_item_alloc_len(S_LEN("old"));
tv_copy(oldtv, &v->di_tv);
tv_dict_add(argv[2].vval.v_dict, v);
diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c
index 1c07fc4d45..4d7214205d 100644
--- a/src/nvim/eval/vars.c
+++ b/src/nvim/eval/vars.c
@@ -1348,12 +1348,8 @@ void set_var_const(const char *name, const size_t name_len, typval_T *const tv,
}
if (watched) {
- if (oldtv.v_type == VAR_UNKNOWN) {
- tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, NULL);
- } else {
- tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv);
- tv_clear(&oldtv);
- }
+ tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv);
+ tv_clear(&oldtv);
}
if (is_const) {
diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c
index 9b1890403e..498f956ed9 100644
--- a/src/nvim/lua/stdlib.c
+++ b/src/nvim/lua/stdlib.c
@@ -369,12 +369,19 @@ int nlua_setvar(lua_State *lstate)
return 0;
}
+ bool watched = tv_dict_is_watched(dict);
+
if (del) {
// Delete the key
if (di == NULL) {
// Doesn't exist, nothing to do
return 0;
} else {
+ // Notify watchers
+ if (watched) {
+ tv_dict_watcher_notify(dict, key.data, NULL, &di->di_tv);
+ }
+
// Delete the entry
tv_dict_item_remove(dict, di);
}
@@ -388,17 +395,29 @@ int nlua_setvar(lua_State *lstate)
return luaL_error(lstate, "Couldn't convert lua value");
}
+ typval_T oldtv = TV_INITIAL_VALUE;
+
if (di == NULL) {
// Need to create an entry
di = tv_dict_item_alloc_len(key.data, key.size);
tv_dict_add(dict, di);
} else {
+ if (watched) {
+ tv_copy(&di->di_tv, &oldtv);
+ }
// Clear the old value
tv_clear(&di->di_tv);
}
// Update the value
tv_copy(&tv, &di->di_tv);
+
+ // Notify watchers
+ if (watched) {
+ tv_dict_watcher_notify(dict, key.data, &tv, &oldtv);
+ tv_clear(&oldtv);
+ }
+
// Clear the temporary variable
tv_clear(&tv);
}