aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-12-18 09:05:59 +0800
committerGitHub <noreply@github.com>2023-12-18 09:05:59 +0800
commit6abdc1ac1f904173d01efcf440d1460c001bc299 (patch)
tree1adbd10cee16558fd68e93d2209c400e01a85bc7 /src
parente164f4c2715c97b48607bb6339eac3aff7106c47 (diff)
downloadrneovim-6abdc1ac1f904173d01efcf440d1460c001bc299.tar.gz
rneovim-6abdc1ac1f904173d01efcf440d1460c001bc299.tar.bz2
rneovim-6abdc1ac1f904173d01efcf440d1460c001bc299.zip
refactor: split WIN_EXECUTE() into two functions (#26627)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/clint.py1
-rw-r--r--src/nvim/api/window.c6
-rw-r--r--src/nvim/eval/window.c80
-rw-r--r--src/nvim/eval/window.h70
4 files changed, 90 insertions, 67 deletions
diff --git a/src/clint.py b/src/clint.py
index 446593303b..51155f0038 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -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",
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index d18971c756..7321d52e17 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -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;
}
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)) {
diff --git a/src/nvim/eval/window.h b/src/nvim/eval/window.h
index ed879c895a..1b2817edf0 100644
--- a/src/nvim/eval/window.h
+++ b/src/nvim/eval/window.h
@@ -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"