diff options
author | smolck <46855713+smolck@users.noreply.github.com> | 2021-08-14 12:19:05 -0500 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2022-09-27 14:47:53 +0200 |
commit | c7d30c152d1639523d05154e245ea60ed9a51a2b (patch) | |
tree | 9e329b4448ef83620d46160741791a6b3c4da86c /src | |
parent | 1d337d4e2f2265b13ecf19a3bc17ad302d3b0d96 (diff) | |
download | rneovim-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.c | 18 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 2 | ||||
-rw-r--r-- | src/nvim/eval/vars.c | 8 | ||||
-rw-r--r-- | src/nvim/lua/stdlib.c | 19 |
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); } |