diff options
author | bfredl <bjorn.linse@gmail.com> | 2024-12-10 14:03:44 +0100 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2024-12-16 12:46:59 +0100 |
commit | 2d6f57b2891247f9ca0f6fb75c4b93fb2c714dc4 (patch) | |
tree | d7bb06b9366e0640d4299a3c7adce644f8e4086e /src/nvim/window.c | |
parent | 9c6a3703bb15d56fecdd962512f69f0ccf6d398c (diff) | |
download | rneovim-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.c | 42 |
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); } } } |