mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
refactor: split WIN_EXECUTE() into two functions (#26627)
This commit is contained in:
parent
e164f4c271
commit
6abdc1ac1f
1
Makefile
1
Makefile
@ -154,7 +154,6 @@ iwyu: build/.ran-cmake
|
||||
|src/nvim/eval/typval.h\
|
||||
|src/nvim/eval/typval_defs.h\
|
||||
|src/nvim/eval/userfunc.h\
|
||||
|src/nvim/eval/window.h\
|
||||
|src/nvim/event/libuv_process.h\
|
||||
|src/nvim/event/loop.h\
|
||||
|src/nvim/event/process.h\
|
||||
|
@ -912,7 +912,6 @@ def CheckIncludes(filename, lines, error):
|
||||
"src/nvim/eval/typval.h",
|
||||
"src/nvim/eval/typval_defs.h",
|
||||
"src/nvim/eval/userfunc.h",
|
||||
"src/nvim/eval/window.h",
|
||||
"src/nvim/event/libuv_process.h",
|
||||
"src/nvim/event/loop.h",
|
||||
"src/nvim/event/process.h",
|
||||
|
@ -435,10 +435,12 @@ Object nvim_win_call(Window window, LuaRef fun, Error *err)
|
||||
|
||||
try_start();
|
||||
Object res = OBJECT_INIT;
|
||||
WIN_EXECUTE(win, tabpage, {
|
||||
win_execute_T win_execute_args;
|
||||
if (win_execute_before(&win_execute_args, win, tabpage)) {
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
res = nlua_call_ref(fun, NULL, args, true, err);
|
||||
});
|
||||
}
|
||||
win_execute_after(&win_execute_args);
|
||||
try_end(err);
|
||||
return res;
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -1,20 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nvim/buffer.h"
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/cursor.h"
|
||||
#include "nvim/eval/typval_defs.h"
|
||||
#include "nvim/globals.h"
|
||||
#include "nvim/mark.h"
|
||||
#include "nvim/option_defs.h"
|
||||
#include "nvim/option_vars.h"
|
||||
#include "nvim/os/fs.h"
|
||||
#include "nvim/eval/typval_defs.h" // IWYU pragma: keep
|
||||
#include "nvim/os/os_defs.h"
|
||||
#include "nvim/pos_defs.h"
|
||||
#include "nvim/vim_defs.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/types_defs.h" // IWYU pragma: keep
|
||||
|
||||
/// Structure used by switch_win() to pass values to restore_win()
|
||||
typedef struct {
|
||||
@ -24,53 +16,15 @@ typedef struct {
|
||||
bool sw_visual_active;
|
||||
} switchwin_T;
|
||||
|
||||
/// Execute a block of code in the context of window `wp` in tabpage `tp`.
|
||||
/// Ensures the status line is redrawn and cursor position is valid if it is moved.
|
||||
#define WIN_EXECUTE(wp, tp, block) \
|
||||
do { \
|
||||
win_T *const wp_ = (wp); \
|
||||
const pos_T curpos_ = wp_->w_cursor; \
|
||||
char cwd_[MAXPATHL]; \
|
||||
char autocwd_[MAXPATHL]; \
|
||||
bool apply_acd_ = false; \
|
||||
int cwd_status_ = FAIL; \
|
||||
/* 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)) { \
|
||||
cwd_status_ = os_dirname(cwd_, MAXPATHL); \
|
||||
} \
|
||||
/* If 'acd' is set, check we are using that directory. If yes, then */ \
|
||||
/* apply 'acd' afterwards, otherwise restore the current directory. */ \
|
||||
if (cwd_status_ == OK && p_acd) { \
|
||||
do_autochdir(); \
|
||||
apply_acd_ = os_dirname(autocwd_, MAXPATHL) == OK && strcmp(cwd_, autocwd_) == 0; \
|
||||
} \
|
||||
switchwin_T switchwin_; \
|
||||
if (switch_win_noblock(&switchwin_, wp_, (tp), true) == OK) { \
|
||||
check_cursor(); \
|
||||
block; \
|
||||
} \
|
||||
restore_win_noblock(&switchwin_, true); \
|
||||
if (apply_acd_) { \
|
||||
do_autochdir(); \
|
||||
} else if (cwd_status_ == OK) { \
|
||||
os_chdir(cwd_); \
|
||||
} \
|
||||
/* Update the status line if the cursor moved. */ \
|
||||
if (win_valid(wp_) && !equalpos(curpos_, wp_->w_cursor)) { \
|
||||
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); \
|
||||
} \
|
||||
} while (false)
|
||||
/// Structure used by win_execute_before() to pass values to win_execute_after()
|
||||
typedef struct {
|
||||
win_T *wp;
|
||||
pos_T curpos;
|
||||
char cwd[MAXPATHL];
|
||||
int cwd_status;
|
||||
bool apply_acd;
|
||||
switchwin_T switchwin;
|
||||
} win_execute_T;
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "eval/window.h.generated.h"
|
||||
|
Loading…
Reference in New Issue
Block a user