mirror of
https://github.com/neovim/neovim.git
synced 2025-09-17 08:48:16 +00:00
vim-patch:8.2.2533: Vim9: cannot use a range with :unlet
Problem: Vim9: cannot use a range with :unlet.
Solution: Implement ISN_UNLETRANGE.
5b5ae29bd3
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -1604,13 +1604,7 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const
|
|||||||
|
|
||||||
lp->ll_dict = NULL;
|
lp->ll_dict = NULL;
|
||||||
lp->ll_list = lp->ll_tv->vval.v_list;
|
lp->ll_list = lp->ll_tv->vval.v_list;
|
||||||
lp->ll_li = tv_list_find(lp->ll_list, (int)lp->ll_n1);
|
lp->ll_li = tv_list_find_index(lp->ll_list, &lp->ll_n1);
|
||||||
if (lp->ll_li == NULL) {
|
|
||||||
if (lp->ll_n1 < 0) {
|
|
||||||
lp->ll_n1 = 0;
|
|
||||||
lp->ll_li = tv_list_find(lp->ll_list, (int)lp->ll_n1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lp->ll_li == NULL) {
|
if (lp->ll_li == NULL) {
|
||||||
tv_clear(&var2);
|
tv_clear(&var2);
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
|
@@ -1507,6 +1507,21 @@ const char *tv_list_find_str(list_T *const l, const int n)
|
|||||||
return tv_get_string(TV_LIST_ITEM_TV(li));
|
return tv_get_string(TV_LIST_ITEM_TV(li));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like tv_list_find() but when a negative index is used that is not found use
|
||||||
|
/// zero and set "idx" to zero. Used for first index of a range.
|
||||||
|
listitem_T *tv_list_find_index(list_T *const l, long *const idx)
|
||||||
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
listitem_T *li = tv_list_find(l, (int)(*idx));
|
||||||
|
if (li == NULL) {
|
||||||
|
if (*idx < 0) {
|
||||||
|
*idx = 0;
|
||||||
|
li = tv_list_find(l, (int)(*idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return li;
|
||||||
|
}
|
||||||
|
|
||||||
/// Locate item in a list and return its index
|
/// Locate item in a list and return its index
|
||||||
///
|
///
|
||||||
/// @param[in] l List to search.
|
/// @param[in] l List to search.
|
||||||
|
@@ -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))) {
|
lp->ll_name_len))) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
} else if (lp->ll_range) {
|
} else if (lp->ll_range) {
|
||||||
assert(lp->ll_list != NULL);
|
if (list_unlet_range(lp->ll_list, lp->ll_li, lp->ll_name, lp->ll_name_len,
|
||||||
// Delete a range of List items.
|
lp->ll_n1, !lp->ll_empty2, lp->ll_n2) == FAIL) {
|
||||||
listitem_T *const first_li = lp->ll_li;
|
return FAIL;
|
||||||
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;
|
|
||||||
}
|
|
||||||
tv_list_remove_items(lp->ll_list, first_li, last_li);
|
|
||||||
} else {
|
} else {
|
||||||
if (lp->ll_list != NULL) {
|
if (lp->ll_list != NULL) {
|
||||||
// unlet a List item.
|
// 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;
|
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
|
/// unlet a variable
|
||||||
///
|
///
|
||||||
/// @param[in] name Variable name to unlet.
|
/// @param[in] name Variable name to unlet.
|
||||||
|
Reference in New Issue
Block a user