diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-06-12 15:38:53 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-06-12 17:20:55 +0800 |
commit | a0cb53eca7a04326dd857cf33fac1154aff7773a (patch) | |
tree | 73d0046d0cd7752b0503e60b5c55cd1f0b512bbc /src/nvim/eval/vars.c | |
parent | 551cc3a2a3e2ee180234910cbe2ef81bd37508de (diff) | |
download | rneovim-a0cb53eca7a04326dd857cf33fac1154aff7773a.tar.gz rneovim-a0cb53eca7a04326dd857cf33fac1154aff7773a.tar.bz2 rneovim-a0cb53eca7a04326dd857cf33fac1154aff7773a.zip |
vim-patch:8.2.2533: Vim9: cannot use a range with :unlet
Problem: Vim9: cannot use a range with :unlet.
Solution: Implement ISN_UNLETRANGE.
https://github.com/vim/vim/commit/5b5ae29bd3d7b832b6f15320430f7f191e0abd1f
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat (limited to 'src/nvim/eval/vars.c')
-rw-r--r-- | src/nvim/eval/vars.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 0663c3c54c..f988a49e6c 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -1056,25 +1056,10 @@ static int do_unlet_var(lval_T *lp, char *name_end, exarg_T *eap, int deep FUNC_ lp->ll_name_len))) { return FAIL; } else if (lp->ll_range) { - assert(lp->ll_list != NULL); - // Delete a range of List items. - listitem_T *const first_li = lp->ll_li; - listitem_T *last_li = first_li; - while (true) { - listitem_T *const li = TV_LIST_ITEM_NEXT(lp->ll_list, lp->ll_li); - if (value_check_lock(TV_LIST_ITEM_TV(lp->ll_li)->v_lock, - lp->ll_name, - lp->ll_name_len)) { - return false; - } - lp->ll_li = li; - lp->ll_n1++; - if (lp->ll_li == NULL || (!lp->ll_empty2 && lp->ll_n2 < lp->ll_n1)) { - break; - } - last_li = lp->ll_li; + if (list_unlet_range(lp->ll_list, lp->ll_li, lp->ll_name, lp->ll_name_len, + lp->ll_n1, !lp->ll_empty2, lp->ll_n2) == FAIL) { + return FAIL; } - tv_list_remove_items(lp->ll_list, first_li, last_li); } else { if (lp->ll_list != NULL) { // unlet a List item. @@ -1107,6 +1092,31 @@ static int do_unlet_var(lval_T *lp, char *name_end, exarg_T *eap, int deep FUNC_ return ret; } +/// Unlet one item or a range of items from a list. +/// Return OK or FAIL. +static int list_unlet_range(list_T *const l, listitem_T *const li_first, const char *const name, + const size_t name_len, const long n1_arg, const bool has_n2, + const long n2) +{ + assert(l != NULL); + // Delete a range of List items. + listitem_T *li_last = li_first; + long n1 = n1_arg; + while (true) { + if (value_check_lock(TV_LIST_ITEM_TV(li_last)->v_lock, name, name_len)) { + return FAIL; + } + listitem_T *const li = TV_LIST_ITEM_NEXT(l, li_last); + n1++; + if (li == NULL || (has_n2 && n2 < n1)) { + break; + } + li_last = li; + } + tv_list_remove_items(l, li_first, li_last); + return OK; +} + /// unlet a variable /// /// @param[in] name Variable name to unlet. |