diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-12-18 09:05:59 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-18 09:05:59 +0800 |
commit | 6abdc1ac1f904173d01efcf440d1460c001bc299 (patch) | |
tree | 1adbd10cee16558fd68e93d2209c400e01a85bc7 /src/nvim/eval/window.c | |
parent | e164f4c2715c97b48607bb6339eac3aff7106c47 (diff) | |
download | rneovim-6abdc1ac1f904173d01efcf440d1460c001bc299.tar.gz rneovim-6abdc1ac1f904173d01efcf440d1460c001bc299.tar.bz2 rneovim-6abdc1ac1f904173d01efcf440d1460c001bc299.zip |
refactor: split WIN_EXECUTE() into two functions (#26627)
Diffstat (limited to 'src/nvim/eval/window.c')
-rw-r--r-- | src/nvim/eval/window.c | 80 |
1 files changed, 74 insertions, 6 deletions
diff --git a/src/nvim/eval/window.c b/src/nvim/eval/window.c index e0abbad477..d1ee2ea356 100644 --- a/src/nvim/eval/window.c +++ b/src/nvim/eval/window.c @@ -9,7 +9,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/cursor.h" #include "nvim/eval/funcs.h" #include "nvim/eval/typval.h" @@ -19,9 +18,12 @@ #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/macros_defs.h" +#include "nvim/mark.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/move.h" +#include "nvim/option_vars.h" +#include "nvim/os/fs.h" #include "nvim/pos_defs.h" #include "nvim/types_defs.h" #include "nvim/vim_defs.h" @@ -480,6 +482,68 @@ void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) rettv->vval.v_number = nr; } +/// Switch to a window for executing user code. +/// Caller must call win_execute_after() later regardless of return value. +/// +/// @return whether switching the window succeded. +bool win_execute_before(win_execute_T *args, win_T *wp, tabpage_T *tp) +{ + args->wp = wp; + args->curpos = wp->w_cursor; + args->cwd_status = FAIL; + args->apply_acd = false; + + // Getting and setting directory can be slow on some systems, only do + // this when the current or target window/tab have a local directory or + // 'acd' is set. + if (curwin != wp + && (curwin->w_localdir != NULL || wp->w_localdir != NULL + || (curtab != tp && (curtab->tp_localdir != NULL || tp->tp_localdir != NULL)) + || p_acd)) { + args->cwd_status = os_dirname(args->cwd, MAXPATHL); + } + + // If 'acd' is set, check we are using that directory. If yes, then + // apply 'acd' afterwards, otherwise restore the current directory. + if (args->cwd_status == OK && p_acd) { + do_autochdir(); + char autocwd[MAXPATHL]; + if (os_dirname(autocwd, MAXPATHL) == OK) { + args->apply_acd = strcmp(args->cwd, autocwd) == 0; + } + } + + if (switch_win_noblock(&args->switchwin, wp, tp, true) == OK) { + check_cursor(); + return true; + } + return false; +} + +/// Restore the previous window after executing user code. +void win_execute_after(win_execute_T *args) +{ + restore_win_noblock(&args->switchwin, true); + + if (args->apply_acd) { + do_autochdir(); + } else if (args->cwd_status == OK) { + os_chdir(args->cwd); + } + + // Update the status line if the cursor moved. + if (win_valid(args->wp) && !equalpos(args->curpos, args->wp->w_cursor)) { + args->wp->w_redr_status = true; + } + + // In case the command moved the cursor or changed the Visual area, + // check it is valid. + check_cursor(); + if (VIsual_active) { + check_pos(curbuf, &VIsual); + } +} + /// "win_execute(win_id, command)" function void f_win_execute(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { @@ -494,7 +558,11 @@ void f_win_execute(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } - WIN_EXECUTE(wp, tp, execute_common(argvars, rettv, 1)); + win_execute_T win_execute_args; + if (win_execute_before(&win_execute_args, wp, tp)) { + execute_common(argvars, rettv, 1); + } + win_execute_after(&win_execute_args); } /// "win_findbuf()" function @@ -914,16 +982,16 @@ int switch_win_noblock(switchwin_T *switchwin, win_T *win, tabpage_T *tp, bool n return OK; } -// Restore current tabpage and window saved by switch_win(), if still valid. -// When "no_display" is true the display won't be affected, no redraw is -// triggered. +/// Restore current tabpage and window saved by switch_win(), if still valid. +/// When "no_display" is true the display won't be affected, no redraw is +/// triggered. void restore_win(switchwin_T *switchwin, bool no_display) { restore_win_noblock(switchwin, no_display); unblock_autocmds(); } -// As restore_win() but without unblocking autocommands. +/// As restore_win() but without unblocking autocommands. void restore_win_noblock(switchwin_T *switchwin, bool no_display) { if (switchwin->sw_curtab != NULL && valid_tabpage(switchwin->sw_curtab)) { |