mirror of
https://github.com/vim/vim.git
synced 2025-08-26 20:03:41 -04:00
patch 9.1.0556: :bwipe doesn't remove file from jumplist of other tabpages
Problem: :bwipe doesn't remove file from jumplist and tagstack of other tabpages. Time complexity of mark_forget_file() is O(n^2) when removing all entries (after v9.1.0554) Solution: Use FOR_ALL_TAB_WINDOWS(). Start the loops over the arrays from the end instead of the start (zeertzjq) closes: #15199 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
a3a14d5469
commit
2e7d89b398
@ -750,13 +750,14 @@ aucmd_abort:
|
|||||||
*/
|
*/
|
||||||
if (wipe_buf)
|
if (wipe_buf)
|
||||||
{
|
{
|
||||||
win_T *wp;
|
tabpage_T *tp;
|
||||||
|
win_T *wp;
|
||||||
|
|
||||||
// Do not wipe out the buffer if it is used in a window.
|
// Do not wipe out the buffer if it is used in a window.
|
||||||
if (buf->b_nwindows > 0)
|
if (buf->b_nwindows > 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
FOR_ALL_WINDOWS(wp)
|
FOR_ALL_TAB_WINDOWS(tp, wp)
|
||||||
mark_forget_file(wp, buf->b_fnum);
|
mark_forget_file(wp, buf->b_fnum);
|
||||||
|
|
||||||
if (action == DOBUF_WIPE_REUSE)
|
if (action == DOBUF_WIPE_REUSE)
|
||||||
|
14
src/mark.c
14
src/mark.c
@ -138,28 +138,26 @@ mark_forget_file(win_T *wp, int fnum)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < wp->w_jumplistlen; ++i)
|
for (i = wp->w_jumplistlen - 1; i >= 0; --i)
|
||||||
if (wp->w_jumplist[i].fmark.fnum == fnum)
|
if (wp->w_jumplist[i].fmark.fnum == fnum)
|
||||||
{
|
{
|
||||||
vim_free(wp->w_jumplist[i].fname);
|
vim_free(wp->w_jumplist[i].fname);
|
||||||
mch_memmove(&wp->w_jumplist[i], &wp->w_jumplist[i + 1],
|
|
||||||
(wp->w_jumplistlen - i - 1) * sizeof(xfmark_T));
|
|
||||||
if (wp->w_jumplistidx > i)
|
if (wp->w_jumplistidx > i)
|
||||||
--wp->w_jumplistidx;
|
--wp->w_jumplistidx;
|
||||||
--wp->w_jumplistlen;
|
--wp->w_jumplistlen;
|
||||||
--i;
|
mch_memmove(&wp->w_jumplist[i], &wp->w_jumplist[i + 1],
|
||||||
|
(wp->w_jumplistlen - i) * sizeof(wp->w_jumplist[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < wp->w_tagstacklen; i++)
|
for (i = wp->w_tagstacklen - 1; i >= 0; --i)
|
||||||
if (wp->w_tagstack[i].fmark.fnum == fnum)
|
if (wp->w_tagstack[i].fmark.fnum == fnum)
|
||||||
{
|
{
|
||||||
tagstack_clear_entry(&wp->w_tagstack[i]);
|
tagstack_clear_entry(&wp->w_tagstack[i]);
|
||||||
mch_memmove(&wp->w_tagstack[i], &wp->w_tagstack[i + 1],
|
|
||||||
(wp->w_tagstacklen - i - 1) * sizeof(taggy_T));
|
|
||||||
if (wp->w_tagstackidx > i)
|
if (wp->w_tagstackidx > i)
|
||||||
--wp->w_tagstackidx;
|
--wp->w_tagstackidx;
|
||||||
--wp->w_tagstacklen;
|
--wp->w_tagstacklen;
|
||||||
--i;
|
mch_memmove(&wp->w_tagstack[i], &wp->w_tagstack[i + 1],
|
||||||
|
(wp->w_tagstacklen - i) * sizeof(wp->w_tagstack[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ func Test_getjumplist()
|
|||||||
call assert_equal(4, l[1])
|
call assert_equal(4, l[1])
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_jumplist_invalid()
|
func Test_jumplist_wipe_buf()
|
||||||
new
|
new
|
||||||
clearjumps
|
clearjumps
|
||||||
" Put some random text and fill the jump list.
|
" Put some random text and fill the jump list.
|
||||||
@ -72,6 +72,50 @@ func Test_jumplist_invalid()
|
|||||||
call assert_equal([[], 0], getjumplist())
|
call assert_equal([[], 0], getjumplist())
|
||||||
let jumps = execute(':jumps')
|
let jumps = execute(':jumps')
|
||||||
call assert_equal('>', jumps[-1:])
|
call assert_equal('>', jumps[-1:])
|
||||||
|
|
||||||
|
" Put some random text and fill the jump list.
|
||||||
|
call setline(1, ['foo', 'bar', 'baz'])
|
||||||
|
setl bufhidden=hide
|
||||||
|
|
||||||
|
" References to wiped buffer are deleted with multiple tabpages.
|
||||||
|
let [w1, t1] = [win_getid(), tabpagenr()]
|
||||||
|
clearjumps
|
||||||
|
normal G
|
||||||
|
normal gg
|
||||||
|
enew
|
||||||
|
|
||||||
|
split XXJumpListBuffer
|
||||||
|
let [w2, t2] = [win_getid(), tabpagenr()]
|
||||||
|
clearjumps
|
||||||
|
normal G
|
||||||
|
normal gg
|
||||||
|
enew
|
||||||
|
|
||||||
|
tabnew XXJumpListBuffer
|
||||||
|
let [w3, t3] = [win_getid(), tabpagenr()]
|
||||||
|
clearjumps
|
||||||
|
normal G
|
||||||
|
normal gg
|
||||||
|
enew
|
||||||
|
|
||||||
|
split XXJumpListBuffer
|
||||||
|
let [w4, t4] = [win_getid(), tabpagenr()]
|
||||||
|
clearjumps
|
||||||
|
normal G
|
||||||
|
normal gg
|
||||||
|
enew
|
||||||
|
|
||||||
|
for [w, t] in [[w1, t1], [w2, t2], [w3, t3], [w4, t4]]
|
||||||
|
call assert_equal(2, len(getjumplist(w, t)[0]))
|
||||||
|
endfor
|
||||||
|
|
||||||
|
bwipe! XXJumpListBuffer
|
||||||
|
|
||||||
|
for [w, t] in [[w1, t1], [w2, t2], [w3, t3], [w4, t4]]
|
||||||
|
call assert_equal(0, len(getjumplist(w, t)[0]))
|
||||||
|
endfor
|
||||||
|
|
||||||
|
%bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Test for '' mark in an empty buffer
|
" Test for '' mark in an empty buffer
|
||||||
|
@ -975,8 +975,46 @@ func Test_tag_stack()
|
|||||||
call assert_equal(0, t.length)
|
call assert_equal(0, t.length)
|
||||||
call assert_equal(1, t.curidx)
|
call assert_equal(1, t.curidx)
|
||||||
|
|
||||||
|
" References to wiped buffer are deleted with multiple tabpages.
|
||||||
|
let w1 = win_getid()
|
||||||
|
call settagstack(1, {'items' : []})
|
||||||
|
for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor
|
||||||
|
enew
|
||||||
|
|
||||||
|
new
|
||||||
|
let w2 = win_getid()
|
||||||
|
call settagstack(1, {'items' : []})
|
||||||
|
for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor
|
||||||
|
enew
|
||||||
|
|
||||||
|
tabnew
|
||||||
|
let w3 = win_getid()
|
||||||
|
call settagstack(1, {'items' : []})
|
||||||
|
for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor
|
||||||
|
enew
|
||||||
|
|
||||||
|
new
|
||||||
|
let w4 = win_getid()
|
||||||
|
call settagstack(1, {'items' : []})
|
||||||
|
for i in range(10, 20) | edit Xtest | exe "tag var" .. i | endfor
|
||||||
|
enew
|
||||||
|
|
||||||
|
for w in [w1, w2, w3, w4]
|
||||||
|
let t = gettagstack(w)
|
||||||
|
call assert_equal(11, t.length)
|
||||||
|
call assert_equal(12, t.curidx)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
bwipe! Xtest
|
||||||
|
|
||||||
|
for w in [w1, w2, w3, w4]
|
||||||
|
let t = gettagstack(w)
|
||||||
|
call assert_equal(0, t.length)
|
||||||
|
call assert_equal(1, t.curidx)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
%bwipe!
|
||||||
set tags&
|
set tags&
|
||||||
%bwipe
|
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Test for browsing multiple matching tags
|
" Test for browsing multiple matching tags
|
||||||
|
@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
556,
|
||||||
/**/
|
/**/
|
||||||
555,
|
555,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user