diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 37 | ||||
-rw-r--r-- | src/nvim/mark.c | 51 | ||||
-rw-r--r-- | src/nvim/tag.c | 2 | ||||
-rw-r--r-- | src/nvim/tag.h | 1 |
4 files changed, 61 insertions, 30 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 3812ff6b44..6878b02a6e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -699,6 +699,9 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i if (buf->b_nwindows > 0) { return false; } + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + mark_forget_file(wp, buf->b_fnum); + } if (buf->b_sfname != buf->b_ffname) { XFREE_CLEAR(buf->b_sfname); } else { @@ -1184,32 +1187,6 @@ static int empty_curbuf(bool close_others, int forceit, int action) return retval; } -/// Remove every jump list entry referring to a given buffer. -/// This function will also adjust the current jump list index. -void buf_remove_from_jumplist(buf_T *deleted_buf) -{ - // Remove all jump list entries that match the deleted buffer. - for (int i = curwin->w_jumplistlen - 1; i >= 0; i--) { - buf_T *buf = buflist_findnr(curwin->w_jumplist[i].fmark.fnum); - - if (buf == deleted_buf) { - // Found an entry that we want to delete. - curwin->w_jumplistlen -= 1; - - // If the current jump list index behind the entry we want to - // delete, move it back by one. - if (curwin->w_jumplistidx > i && curwin->w_jumplistidx > 0) { - curwin->w_jumplistidx -= 1; - } - - // Actually remove the entry from the jump list. - for (int d = i; d < curwin->w_jumplistlen; d++) { - curwin->w_jumplist[d] = curwin->w_jumplist[d + 1]; - } - } - } -} - /// Implementation of the commands for the buffer list. /// /// action == DOBUF_GOTO go to specified buffer @@ -1364,6 +1341,8 @@ int do_buffer(int action, int start, int dir, int count, int forceit) } } + int buf_fnum = buf->b_fnum; + // When closing the current buffer stop Visual mode. if (buf == curbuf && VIsual_active) { end_visual_mode(); @@ -1398,7 +1377,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit) if (buf != curbuf) { if (jop_flags & JOP_UNLOAD) { // Remove the buffer to be deleted from the jump list. - buf_remove_from_jumplist(buf); + mark_jumplist_forget_file(curwin, buf_fnum); } close_windows(buf, false); @@ -1423,8 +1402,8 @@ int do_buffer(int action, int start, int dir, int count, int forceit) buf = au_new_curbuf.br_buf; } else if (curwin->w_jumplistlen > 0) { if (jop_flags & JOP_UNLOAD) { - // Remove the current buffer from the jump list. - buf_remove_from_jumplist(curbuf); + // Remove the buffer from the jump list. + mark_jumplist_forget_file(curwin, buf_fnum); } // It's possible that we removed all jump list entries, in that case we need to try another diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 16f444a316..fae28ef6e1 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -43,6 +43,7 @@ #include "nvim/pos_defs.h" #include "nvim/quickfix.h" #include "nvim/strings.h" +#include "nvim/tag.h" #include "nvim/textobject.h" #include "nvim/types_defs.h" #include "nvim/vim_defs.h" @@ -165,6 +166,56 @@ int setmark_pos(int c, pos_T *pos, int fnum, fmarkv_T *view_pt) return FAIL; } +/// Remove every jump list entry referring to a given buffer. +/// This function will also adjust the current jump list index. +void mark_jumplist_forget_file(win_T *wp, int fnum) +{ + // Remove all jump list entries that match the deleted buffer. + for (int i = wp->w_jumplistlen - 1; i >= 0; i--) { + if (wp->w_jumplist[i].fmark.fnum == fnum) { + // Found an entry that we want to delete. + free_xfmark(wp->w_jumplist[i]); + + // If the current jump list index is behind the entry we want to delete, + // move it back by one. + if (wp->w_jumplistidx > i) { + wp->w_jumplistidx--; + } + + // Actually remove the entry from the jump list. + wp->w_jumplistlen--; + memmove(&wp->w_jumplist[i], &wp->w_jumplist[i + 1], + (size_t)(wp->w_jumplistlen - i) * sizeof(wp->w_jumplist[i])); + } + } +} + +/// Delete every entry referring to file "fnum" from both the jumplist and the +/// tag stack. +void mark_forget_file(win_T *wp, int fnum) +{ + mark_jumplist_forget_file(wp, fnum); + + // Remove all tag stack entries that match the deleted buffer. + for (int i = wp->w_tagstacklen - 1; i >= 0; i--) { + if (wp->w_tagstack[i].fmark.fnum == fnum) { + // Found an entry that we want to delete. + tagstack_clear_entry(&wp->w_tagstack[i]); + + // If the current tag stack index is behind the entry we want to delete, + // move it back by one. + if (wp->w_tagstackidx > i) { + wp->w_tagstackidx--; + } + + // Actually remove the entry from the tag stack. + wp->w_tagstacklen--; + memmove(&wp->w_tagstack[i], &wp->w_tagstack[i + 1], + (size_t)(wp->w_tagstacklen - i) * sizeof(wp->w_tagstack[i])); + } + } +} + // Set the previous context mark to the current position and add it to the // jump list. void setpcmark(void) diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 8f6342bfcc..90269c776e 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -3184,7 +3184,7 @@ static int find_extra(char **pp) // // Free a single entry in a tag stack // -static void tagstack_clear_entry(taggy_T *item) +void tagstack_clear_entry(taggy_T *item) { XFREE_CLEAR(item->tagname); XFREE_CLEAR(item->user_data); diff --git a/src/nvim/tag.h b/src/nvim/tag.h index 42196b44b7..1c6f41050d 100644 --- a/src/nvim/tag.h +++ b/src/nvim/tag.h @@ -1,5 +1,6 @@ #pragma once +#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/option_defs.h" // IWYU pragma: keep |