diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-07-10 10:35:12 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-10 10:35:12 +0800 |
commit | 158ffd646d18eb26ca7e04e9cb9110305577b9c8 (patch) | |
tree | 927bad31846421670891666a6829c53a41b9830e /src/nvim/mark.c | |
parent | 545aafbeb80eb52c182ce139800489b392a12d0d (diff) | |
download | rneovim-158ffd646d18eb26ca7e04e9cb9110305577b9c8.tar.gz rneovim-158ffd646d18eb26ca7e04e9cb9110305577b9c8.tar.bz2 rneovim-158ffd646d18eb26ca7e04e9cb9110305577b9c8.zip |
vim-patch:9.1.0554: :bw leaves jumplist and tagstack data around (#29639)
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: vim/vim#8201
closes: vim/vim#15185
https://github.com/vim/vim/commit/4ff3a9b1e3ba45f9dbd0ea8c721f27d9315c4d93
Co-authored-by: LemonBoy <thatlemon@gmail.com>
Diffstat (limited to 'src/nvim/mark.c')
-rw-r--r-- | src/nvim/mark.c | 51 |
1 files changed, 51 insertions, 0 deletions
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) |