mirror of
https://github.com/neovim/neovim.git
synced 2025-09-20 02:08:17 +00:00
eval: Replace some tv_list_item_remove() calls
There is nothing wrong with them, just it is generally better to remove a range then to remove items individually.
This commit is contained in:
@@ -2887,26 +2887,25 @@ static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit)
|
|||||||
lp->ll_name_len))) {
|
lp->ll_name_len))) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
} else if (lp->ll_range) {
|
} else if (lp->ll_range) {
|
||||||
listitem_T *li;
|
// Delete a range of List items.
|
||||||
listitem_T *ll_li = lp->ll_li;
|
listitem_T *const first_li = lp->ll_li;
|
||||||
int ll_n1 = lp->ll_n1;
|
listitem_T *last_li = first_li;
|
||||||
|
for (;;) {
|
||||||
while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1)) {
|
listitem_T *const li = TV_LIST_ITEM_NEXT(lp->ll_list, lp->ll_li);
|
||||||
li = TV_LIST_ITEM_NEXT(lp->ll_list, ll_li);
|
if (tv_check_lock(TV_LIST_ITEM_TV(lp->ll_li)->v_lock,
|
||||||
if (tv_check_lock(TV_LIST_ITEM_TV(ll_li)->v_lock,
|
|
||||||
(const char *)lp->ll_name,
|
(const char *)lp->ll_name,
|
||||||
lp->ll_name_len)) {
|
lp->ll_name_len)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ll_li = li;
|
lp->ll_li = li;
|
||||||
ll_n1++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete a range of List items.
|
|
||||||
while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) {
|
|
||||||
lp->ll_li = tv_list_item_remove(lp->ll_list, lp->ll_li);
|
|
||||||
lp->ll_n1++;
|
lp->ll_n1++;
|
||||||
|
if (lp->ll_li == NULL || (!lp->ll_empty2 && lp->ll_n2 < lp->ll_n1)) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
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.
|
||||||
@@ -13123,15 +13122,12 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
/*
|
// For a negative line count use only the lines at the end of the file,
|
||||||
* For a negative line count use only the lines at the end of the file,
|
// free the rest.
|
||||||
* free the rest.
|
if (maxline < -tv_list_len(rettv->vval.v_list)) {
|
||||||
*/
|
listitem_T *const first_li = tv_list_find(rettv->vval.v_list, maxline);
|
||||||
if (maxline < 0)
|
listitem_T *const last_li = tv_list_last(rettv->vval.v_list);
|
||||||
while (cnt > -maxline) {
|
tv_list_remove_items(rettv->vval.v_list, first_li, last_li);
|
||||||
tv_list_item_remove(rettv->vval.v_list,
|
|
||||||
tv_list_first(rettv->vval.v_list));
|
|
||||||
cnt--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree(prev);
|
xfree(prev);
|
||||||
|
@@ -284,6 +284,23 @@ void tv_list_drop_items(list_T *const l, listitem_T *const item,
|
|||||||
l->lv_idx_item = NULL;
|
l->lv_idx_item = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like tv_list_drop_items, but also frees all removed items
|
||||||
|
void tv_list_remove_items(list_T *const l, listitem_T *const item,
|
||||||
|
listitem_T *const item2)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
tv_list_drop_items(l, item, item2);
|
||||||
|
for(listitem_T *li = item;;) {
|
||||||
|
tv_clear(TV_LIST_ITEM_TV(li));
|
||||||
|
listitem_T *const nli = li->li_next;
|
||||||
|
xfree(li);
|
||||||
|
if (li == item2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
li = nli;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Move items "item" to "item2" from list "l" to the end of the list "tgt_l"
|
/// Move items "item" to "item2" from list "l" to the end of the list "tgt_l"
|
||||||
///
|
///
|
||||||
/// @param[out] l List to move from.
|
/// @param[out] l List to move from.
|
||||||
|
@@ -444,6 +444,77 @@ describe('typval.c', function()
|
|||||||
alloc_log:check({})
|
alloc_log:check({})
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
describe('remove_items()', function()
|
||||||
|
itp('works', function()
|
||||||
|
local l_tv = lua2typvalt({'1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13'})
|
||||||
|
local l = l_tv.vval.v_list
|
||||||
|
local lis = list_items(l)
|
||||||
|
local strings = map(function(li) return li.li_tv.vval.v_string end, lis)
|
||||||
|
-- Three watchers: pointing to first, middle and last elements.
|
||||||
|
local lws = {
|
||||||
|
list_watch(l, lis[1]),
|
||||||
|
list_watch(l, lis[7]),
|
||||||
|
list_watch(l, lis[13]),
|
||||||
|
}
|
||||||
|
alloc_log:clear()
|
||||||
|
|
||||||
|
lib.tv_list_remove_items(l, lis[1], lis[3])
|
||||||
|
eq({'4', '5', '6', '7', '8', '9', '10', '11', '12', '13'}, typvalt2lua(l_tv))
|
||||||
|
eq({lis[4], lis[7], lis[13]}, {lws[1].lw_item, lws[2].lw_item, lws[3].lw_item})
|
||||||
|
alloc_log:check({
|
||||||
|
a.freed(strings[1]),
|
||||||
|
a.freed(lis[1]),
|
||||||
|
a.freed(strings[2]),
|
||||||
|
a.freed(lis[2]),
|
||||||
|
a.freed(strings[3]),
|
||||||
|
a.freed(lis[3]),
|
||||||
|
})
|
||||||
|
|
||||||
|
lib.tv_list_remove_items(l, lis[11], lis[13])
|
||||||
|
eq({'4', '5', '6', '7', '8', '9', '10'}, typvalt2lua(l_tv))
|
||||||
|
eq({lis[4], lis[7], nil}, {lws[1].lw_item, lws[2].lw_item, lws[3].lw_item == nil and nil})
|
||||||
|
alloc_log:check({
|
||||||
|
a.freed(strings[11]),
|
||||||
|
a.freed(lis[11]),
|
||||||
|
a.freed(strings[12]),
|
||||||
|
a.freed(lis[12]),
|
||||||
|
a.freed(strings[13]),
|
||||||
|
a.freed(lis[13]),
|
||||||
|
})
|
||||||
|
|
||||||
|
lib.tv_list_remove_items(l, lis[6], lis[8])
|
||||||
|
eq({'4', '5', '9', '10'}, typvalt2lua(l_tv))
|
||||||
|
eq({lis[4], lis[9], nil}, {lws[1].lw_item, lws[2].lw_item, lws[3].lw_item == nil and nil})
|
||||||
|
alloc_log:check({
|
||||||
|
a.freed(strings[6]),
|
||||||
|
a.freed(lis[6]),
|
||||||
|
a.freed(strings[7]),
|
||||||
|
a.freed(lis[7]),
|
||||||
|
a.freed(strings[8]),
|
||||||
|
a.freed(lis[8]),
|
||||||
|
})
|
||||||
|
|
||||||
|
lib.tv_list_remove_items(l, lis[4], lis[10])
|
||||||
|
eq(empty_list, typvalt2lua(l_tv))
|
||||||
|
eq({true, true, true}, {lws[1].lw_item == nil, lws[2].lw_item == nil, lws[3].lw_item == nil})
|
||||||
|
alloc_log:check({
|
||||||
|
a.freed(strings[4]),
|
||||||
|
a.freed(lis[4]),
|
||||||
|
a.freed(strings[5]),
|
||||||
|
a.freed(lis[5]),
|
||||||
|
a.freed(strings[9]),
|
||||||
|
a.freed(lis[9]),
|
||||||
|
a.freed(strings[10]),
|
||||||
|
a.freed(lis[10]),
|
||||||
|
})
|
||||||
|
|
||||||
|
lib.tv_list_watch_remove(l, lws[1])
|
||||||
|
lib.tv_list_watch_remove(l, lws[2])
|
||||||
|
lib.tv_list_watch_remove(l, lws[3])
|
||||||
|
|
||||||
|
alloc_log:check({})
|
||||||
|
end)
|
||||||
|
end)
|
||||||
describe('insert', function()
|
describe('insert', function()
|
||||||
describe('()', function()
|
describe('()', function()
|
||||||
itp('works', function()
|
itp('works', function()
|
||||||
|
Reference in New Issue
Block a user