aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/window.c
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2024-12-10 14:03:44 +0100
committerbfredl <bjorn.linse@gmail.com>2024-12-16 12:46:59 +0100
commit2d6f57b2891247f9ca0f6fb75c4b93fb2c714dc4 (patch)
treed7bb06b9366e0640d4299a3c7adce644f8e4086e /src/nvim/window.c
parent9c6a3703bb15d56fecdd962512f69f0ccf6d398c (diff)
downloadrneovim-2d6f57b2891247f9ca0f6fb75c4b93fb2c714dc4.tar.gz
rneovim-2d6f57b2891247f9ca0f6fb75c4b93fb2c714dc4.tar.bz2
rneovim-2d6f57b2891247f9ca0f6fb75c4b93fb2c714dc4.zip
refactor(wininfo): change wininfo from a linked list to an array
"wininfo" is going to be my next victim. The main problem with wininfo is that it is "all or nothing", i e either all state about a buffer in a window is considered valid or none of it is. This needs to be fixed to address some long running grievances. For now this is just a warmup: refactor it from a linked list to a vector.
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r--src/nvim/window.c42
1 files changed, 18 insertions, 24 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 938d9d7618..b1c483547c 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -5175,8 +5175,8 @@ win_T *win_alloc(win_T *after, bool hidden)
return new_wp;
}
-// Free one wininfo_T.
-void free_wininfo(wininfo_T *wip, buf_T *bp)
+// Free one WinInfo.
+void free_wininfo(WinInfo *wip, buf_T *bp)
{
if (wip->wi_optset) {
clear_winopt(&wip->wi_opt);
@@ -5241,30 +5241,24 @@ void win_free(win_T *wp, tabpage_T *tp)
// Remove the window from the b_wininfo lists, it may happen that the
// freed memory is re-used for another window.
FOR_ALL_BUFFERS(buf) {
- for (wininfo_T *wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
+ WinInfo *wip_wp = NULL;
+ size_t pos_null = kv_size(buf->b_wininfo);
+ for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
+ WinInfo *wip = kv_A(buf->b_wininfo, i);
if (wip->wi_win == wp) {
- wininfo_T *wip2;
-
- // If there already is an entry with "wi_win" set to NULL it
- // must be removed, it would never be used.
- // Skip "wip" itself, otherwise Coverity complains.
- for (wip2 = buf->b_wininfo; wip2 != NULL; wip2 = wip2->wi_next) {
- // `wip2 != wip` to satisfy Coverity. #14884
- if (wip2 != wip && wip2->wi_win == NULL) {
- if (wip2->wi_next != NULL) {
- wip2->wi_next->wi_prev = wip2->wi_prev;
- }
- if (wip2->wi_prev == NULL) {
- buf->b_wininfo = wip2->wi_next;
- } else {
- wip2->wi_prev->wi_next = wip2->wi_next;
- }
- free_wininfo(wip2, buf);
- break;
- }
- }
+ wip_wp = wip;
+ } else if (wip->wi_win == NULL) {
+ pos_null = i;
+ }
+ }
- wip->wi_win = NULL;
+ if (wip_wp) {
+ wip_wp->wi_win = NULL;
+ // If there already is an entry with "wi_win" set to NULL it
+ // must be removed, it would never be used.
+ if (pos_null < kv_size(buf->b_wininfo)) {
+ free_wininfo(kv_A(buf->b_wininfo, pos_null), buf);
+ kv_shift(buf->b_wininfo, pos_null, 1);
}
}
}