refactor(ctx): simplify ctx_switch (40674

This commit is contained in:
Justin M. Keyes
2026-07-10 09:08:58 -04:00
committed by GitHub
parent 435734e8db
commit 6a8bb2d62f
2 changed files with 29 additions and 31 deletions

View File

@@ -341,7 +341,7 @@ static void ctx_cwd_restore(CtxSwitch *cs)
XFREE_CLEAR(cs->cs_cwd);
}
/// Return true if "win" is an active entry in ctx_win[] (the pool of temporary scratch windows).
/// Return true if `win` is an active entry in ctx_win[] (the pool of temporary scratch windows).
bool is_ctx_win(win_T *win)
{
for (int i = 0; i < CTX_WIN_COUNT; i++) {
@@ -352,11 +352,12 @@ bool is_ctx_win(win_T *win)
return false;
}
/// Prepares a temporary "autocmd window" showing `buf`: allocated (or reused) from the `ctx_win[]`
/// pool, appended to the window list of the current tabpage, and entered, all without side effects
/// (autocommands, chdir, redraw). Records what ctx_restore() needs to undo it in `cs`.
/// Prepares a temporary "autocmd window" showing `buf`: allocated/reused from the `ctx_win[]` pool
/// and appended to the window list of curtab. Records what ctx_restore() needs to undo in `cs`.
///
/// @return the entered autocmd window (the new curwin).
/// Window lifecycle only: does not enter the window, no side effects (autocmds, chdir, redraw).
///
/// @return the prepared autocmd window.
static win_T *ctx_win_prep(CtxSwitch *cs, buf_T *buf)
{
bool need_append = true; // Append `cw_win` to the window list.
@@ -387,36 +388,26 @@ static win_T *ctx_win_prep(CtxSwitch *cs, buf_T *buf)
buf->b_nwindows++;
win_init_empty(cw_win); // set cursor and topline to safe values
// Make sure w_localdir, tp_localdir and globaldir are NULL to avoid a
// chdir() in win_enter_ext().
// Make sure w_localdir, tp_localdir, globaldir are NULL: the switched-to code runs in the actual
// cwd (no chdir on switch), and a pooled tmp-window must not carry a stale w_localdir.
XFREE_CLEAR(cw_win->w_localdir);
cs->cs_tp_localdir = curtab->tp_localdir;
curtab->tp_localdir = NULL;
cs->cs_globaldir = globaldir;
globaldir = NULL;
block_autocmds(); // We don't want BufEnter/WinEnter autocommands.
if (need_append) {
win_append(lastwin, cw_win, NULL);
pmap_put(int)(&window_handles, cw_win->handle, cw_win);
win_config_float(cw_win, cw_win->w_config);
}
// Prevent chdir() call in win_enter_ext(), through do_autochdir()
const int save_acd = p_acd;
p_acd = false;
// no redrawing and don't set the window title
RedrawingDisabled++;
win_enter(cw_win, false);
RedrawingDisabled--;
p_acd = save_acd;
unblock_autocmds();
return cw_win;
}
/// Removes the temporary "autocmd window" prepared by ctx_win_prep() from the window list (entering
/// it first if needed), and releases its pool slot. Caller must restore curwin (the removed window
/// is curwin) and the directory state saved in "cs".
/// Removes the temp win (FKA "autocmd win") prepared by ctx_win_prep() from the window list
/// (entering it if needed), and releases its pool slot. Caller must restore curwin (the removed
/// window is curwin) and the directory state saved in "cs".
///
/// @return the removed autocmd window.
static win_T *ctx_win_rest(CtxSwitch *cs)
@@ -541,9 +532,12 @@ bool ctx_switch(CtxSwitch *cs, win_T *wp, tabpage_T *tp, buf_T *buf, CtxSwitchFl
if (buf != NULL) {
if (wp == NULL) {
// No window shows "buf": prepare an autocmd window. Anything related to a window (e.g.,
// setting folds) may have unexpected results.
// No window shows `buf`: prepare a temp window. Anything related to a window (e.g., setting
// folds) may have unexpected results.
wp = ctx_win_prep(cs, buf);
// Leave the window we entered "from".
leaving_window(curwin);
prevwin = curwin;
}
assert(win_valid(wp));
} else if (!win_valid(wp)) {
@@ -617,7 +611,7 @@ void ctx_restore(CtxSwitch *cs)
ctx_restore_curwin(cs, firstwin);
// May need to restore insert-mode for a prompt buffer.
// Pairs with the win_enter()..leaving_window() from ctx_win_prep().
// Pairs with the leaving_window() in ctx_switch().
entering_window(curwin);
if (bt_prompt(curbuf)) {
curbuf->b_prompt_insert = cs->cs_prompt_insert;

View File

@@ -2494,12 +2494,14 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
}
}
/// Called when `win` stops being curwin: closing, switching, or leaving its tabpage. Pairs with
/// entering_window(). Only matters for a prompt buffer...
///
/// @see win_enter
void leaving_window(win_T *const win)
FUNC_ATTR_NONNULL_ALL
{
// Only matters for a prompt window.
// Don't do mode changes for a prompt buffer in an autocommand window, as
// it's only used temporarily during an autocommand.
// Not for a ctx window: it shows its buffer only temporarily.
if (!bt_prompt(win->w_buffer) || is_ctx_win(win)) {
return;
}
@@ -2523,12 +2525,14 @@ void leaving_window(win_T *const win)
}
}
/// Called when `win` becomes curwin: switching to it, entering its tabpage, or ctx_restore().
/// Pairs with leaving_window(). Only matters for a prompt buffer...
///
/// @see win_enter
void entering_window(win_T *const win)
FUNC_ATTR_NONNULL_ALL
{
// Only matters for a prompt window.
// Don't do mode changes for a prompt buffer in an autocommand window, as
// it's only used temporarily during an autocommand.
// Not for a ctx window: it shows its buffer only temporarily.
if (!bt_prompt(win->w_buffer) || is_ctx_win(win)) {
return;
}
@@ -2579,7 +2583,7 @@ void close_windows(buf_T *buf, bool keep_curwin)
RedrawingDisabled++;
// Start from lastwin to close floating windows with the same buffer first.
// When the autocommand window is involved win_close() may need to print an error message.
// When the ctx window is involved win_close() may need to print an error message.
for (win_T *wp = lastwin; wp != NULL && (is_ctx_win(lastwin) || !one_window(wp, NULL));) {
if (wp->w_buffer == buf && (!keep_curwin || wp != curwin)
&& !(win_locked(wp) || wp->w_buffer->b_locked > 0)) {
@@ -2648,7 +2652,7 @@ bool one_window(win_T *win, tabpage_T *tp)
}
/// Check if floating windows in tabpage `tp` can be closed.
/// Do not call this when the autocommand window is in use!
/// Do not call this when the ctx window is in use!
///
/// @param tp tabpage to check. Must be NULL for the current tabpage.
/// @return true if all floating windows can be closed