mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 9.1.0554: :bw leaves jumplist and tagstack data around
Problem: :bw leaves jumplist and tagstack data around (Paul "Joey" Clark) Solution: Wipe jumplist and tagstack references to the wiped buffer (LemonBoy) As documented the :bwipeout command brutally deletes all the references to the buffer, so let's make it delete all the entries in the jump list and tag stack referring to the wiped-out buffer. fixes: #8201 closes: #15185 Signed-off-by: LemonBoy <thatlemon@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
d33a518025
commit
4ff3a9b1e3
@@ -41579,6 +41579,7 @@ Changed~
|
|||||||
- allow to specify a priority when defining a new sign |:sign-define|
|
- allow to specify a priority when defining a new sign |:sign-define|
|
||||||
- provide information about function arguments using the get(func, "arity")
|
- provide information about function arguments using the get(func, "arity")
|
||||||
function |get()-func|
|
function |get()-func|
|
||||||
|
- |:bwipe| also wipes jumplist and tagstack data
|
||||||
|
|
||||||
*added-9.2*
|
*added-9.2*
|
||||||
Added ~
|
Added ~
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
*windows.txt* For Vim version 9.1. Last change: 2024 Feb 20
|
*windows.txt* For Vim version 9.1. Last change: 2024 Jul 09
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -1223,7 +1223,8 @@ list of buffers. |unlisted-buffer|
|
|||||||
:bw[ipeout][!] N1 N2 ...
|
:bw[ipeout][!] N1 N2 ...
|
||||||
Like |:bdelete|, but really delete the buffer. Everything
|
Like |:bdelete|, but really delete the buffer. Everything
|
||||||
related to the buffer is lost. All marks in this buffer
|
related to the buffer is lost. All marks in this buffer
|
||||||
become invalid, option settings are lost, etc. Don't use this
|
become invalid, option settings are lost, the jumplist and
|
||||||
|
tagstack data will be purged, etc. Don't use this
|
||||||
unless you know what you are doing. Examples: >
|
unless you know what you are doing. Examples: >
|
||||||
:.+,$bwipeout " wipe out all buffers after the current
|
:.+,$bwipeout " wipe out all buffers after the current
|
||||||
" one
|
" one
|
||||||
|
@@ -750,10 +750,15 @@ aucmd_abort:
|
|||||||
*/
|
*/
|
||||||
if (wipe_buf)
|
if (wipe_buf)
|
||||||
{
|
{
|
||||||
|
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)
|
||||||
|
mark_forget_file(wp, buf->b_fnum);
|
||||||
|
|
||||||
if (action == DOBUF_WIPE_REUSE)
|
if (action == DOBUF_WIPE_REUSE)
|
||||||
{
|
{
|
||||||
// we can re-use this buffer number, store it
|
// we can re-use this buffer number, store it
|
||||||
|
34
src/mark.c
34
src/mark.c
@@ -129,6 +129,40 @@ setmark_pos(int c, pos_T *pos, int fnum)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete every entry referring to file 'fnum' from both the jumplist and the
|
||||||
|
* tag stack.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mark_forget_file(win_T *wp, int fnum)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < wp->w_jumplistlen; ++i)
|
||||||
|
if (wp->w_jumplist[i].fmark.fnum == fnum)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
--wp->w_jumplistidx;
|
||||||
|
--wp->w_jumplistlen;
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < wp->w_tagstacklen; i++)
|
||||||
|
if (wp->w_tagstack[i].fmark.fnum == fnum)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
--wp->w_tagstackidx;
|
||||||
|
--wp->w_tagstacklen;
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the previous context mark to the current position and add it to the
|
* Set the previous context mark to the current position and add it to the
|
||||||
* jump list.
|
* jump list.
|
||||||
|
@@ -28,4 +28,5 @@ void set_last_cursor(win_T *win);
|
|||||||
void free_all_marks(void);
|
void free_all_marks(void);
|
||||||
xfmark_T *get_namedfm(void);
|
xfmark_T *get_namedfm(void);
|
||||||
void f_getmarklist(typval_T *argvars, typval_T *rettv);
|
void f_getmarklist(typval_T *argvars, typval_T *rettv);
|
||||||
|
void mark_forget_file(win_T *wp, int fnum);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -14,4 +14,5 @@ int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file);
|
|||||||
int get_tags(list_T *list, char_u *pat, char_u *buf_fname);
|
int get_tags(list_T *list, char_u *pat, char_u *buf_fname);
|
||||||
void get_tagstack(win_T *wp, dict_T *retdict);
|
void get_tagstack(win_T *wp, dict_T *retdict);
|
||||||
int set_tagstack(win_T *wp, dict_T *d, int action);
|
int set_tagstack(win_T *wp, dict_T *d, int action);
|
||||||
|
void tagstack_clear_entry(taggy_T *item);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -144,7 +144,6 @@ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_
|
|||||||
#if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
|
#if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
|
||||||
static int add_llist_tags(char_u *tag, int num_matches, char_u **matches);
|
static int add_llist_tags(char_u *tag, int num_matches, char_u **matches);
|
||||||
#endif
|
#endif
|
||||||
static void tagstack_clear_entry(taggy_T *item);
|
|
||||||
|
|
||||||
static char_u *tagmatchname = NULL; // name of last used tag
|
static char_u *tagmatchname = NULL; // name of last used tag
|
||||||
|
|
||||||
@@ -4233,7 +4232,7 @@ find_extra(char_u **pp)
|
|||||||
/*
|
/*
|
||||||
* Free a single entry in a tag stack
|
* Free a single entry in a tag stack
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
tagstack_clear_entry(taggy_T *item)
|
tagstack_clear_entry(taggy_T *item)
|
||||||
{
|
{
|
||||||
VIM_CLEAR(item->tagname);
|
VIM_CLEAR(item->tagname);
|
||||||
|
@@ -62,26 +62,16 @@ endfunc
|
|||||||
func Test_jumplist_invalid()
|
func Test_jumplist_invalid()
|
||||||
new
|
new
|
||||||
clearjumps
|
clearjumps
|
||||||
" put some randome text
|
" Put some random text and fill the jump list.
|
||||||
put ='a'
|
call setline(1, ['foo', 'bar', 'baz'])
|
||||||
let prev = bufnr('%')
|
normal G
|
||||||
|
normal gg
|
||||||
setl nomodified bufhidden=wipe
|
setl nomodified bufhidden=wipe
|
||||||
e XXJumpListBuffer
|
e XXJumpListBuffer
|
||||||
let bnr = bufnr('%')
|
" The jump list is empty as the buffer was wiped out.
|
||||||
" 1) empty jumplist
|
call assert_equal([[], 0], getjumplist())
|
||||||
let expected = [[
|
|
||||||
\ {'lnum': 2, 'bufnr': prev, 'col': 0, 'coladd': 0}], 1]
|
|
||||||
call assert_equal(expected, getjumplist())
|
|
||||||
let jumps = execute(':jumps')
|
let jumps = execute(':jumps')
|
||||||
call assert_equal('>', jumps[-1:])
|
call assert_equal('>', jumps[-1:])
|
||||||
" now jump back
|
|
||||||
exe ":norm! \<c-o>"
|
|
||||||
let expected = [[
|
|
||||||
\ {'lnum': 2, 'bufnr': prev, 'col': 0, 'coladd': 0},
|
|
||||||
\ {'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0}], 0]
|
|
||||||
call assert_equal(expected, getjumplist())
|
|
||||||
let jumps = execute(':jumps')
|
|
||||||
call assert_match('> 0 2 0 -invalid-', jumps)
|
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Test for '' mark in an empty buffer
|
" Test for '' mark in an empty buffer
|
||||||
|
@@ -958,6 +958,23 @@ func Test_tag_stack()
|
|||||||
call settagstack(1, {'items' : []})
|
call settagstack(1, {'items' : []})
|
||||||
call assert_fails('pop', 'E73:')
|
call assert_fails('pop', 'E73:')
|
||||||
|
|
||||||
|
" References to wiped buffer are deleted.
|
||||||
|
for i in range(10, 20)
|
||||||
|
edit Xtest
|
||||||
|
exe "tag var" .. i
|
||||||
|
endfor
|
||||||
|
edit Xtest
|
||||||
|
|
||||||
|
let t = gettagstack()
|
||||||
|
call assert_equal(11, t.length)
|
||||||
|
call assert_equal(12, t.curidx)
|
||||||
|
|
||||||
|
bwipe!
|
||||||
|
|
||||||
|
let t = gettagstack()
|
||||||
|
call assert_equal(0, t.length)
|
||||||
|
call assert_equal(1, t.curidx)
|
||||||
|
|
||||||
set tags&
|
set tags&
|
||||||
%bwipe
|
%bwipe
|
||||||
endfunc
|
endfunc
|
||||||
|
@@ -2934,6 +2934,7 @@ func Test_tfirst()
|
|||||||
\ "Xtags", 'D')
|
\ "Xtags", 'D')
|
||||||
call writefile(["one", "two", "three"], "Xfile", 'D')
|
call writefile(["one", "two", "three"], "Xfile", 'D')
|
||||||
call writefile(["one"], "Xother", 'D')
|
call writefile(["one"], "Xother", 'D')
|
||||||
|
tag one
|
||||||
edit Xother
|
edit Xother
|
||||||
|
|
||||||
set winfixbuf
|
set winfixbuf
|
||||||
|
@@ -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 */
|
||||||
|
/**/
|
||||||
|
554,
|
||||||
/**/
|
/**/
|
||||||
553,
|
553,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user