diff options
author | Sean Dewar <6256228+seandewar@users.noreply.github.com> | 2024-02-27 13:25:44 +0000 |
---|---|---|
committer | Sean Dewar <6256228+seandewar@users.noreply.github.com> | 2024-03-08 23:24:06 +0000 |
commit | e7c262f5553c1c6e1de95bcbdc8cfe7cc9d5e55e (patch) | |
tree | ef0a5da5f8708ddd036534367a52975d75b1c37f /src | |
parent | d942c2b9432d81e4b509519bd48fa886e37e9ca8 (diff) | |
download | rneovim-e7c262f5553c1c6e1de95bcbdc8cfe7cc9d5e55e.tar.gz rneovim-e7c262f5553c1c6e1de95bcbdc8cfe7cc9d5e55e.tar.bz2 rneovim-e7c262f5553c1c6e1de95bcbdc8cfe7cc9d5e55e.zip |
fix(api): patch some cmdwin/textlock holes
Problem: there are new ways to escape textlock or break the cmdwin in
nvim_win_set_config and nvim_tabpage_set_win.
Solution: fix them. Use win_goto to check it in nvim_tabpage_set_win and use the
try_start/end pattern like with similar functions such as nvim_set_current_win
(which uses the existing msg_list, if set).
Careful not to use `wp->handle` when printing the window ID in the error message
for nvim_tabpage_set_win, as win_goto autocommands may have freed the window.
On a related note, I have a feeling some API functions ought to be checking
curbuf_locked...
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/tabpage.c | 6 | ||||
-rw-r--r-- | src/nvim/api/win_config.c | 6 | ||||
-rw-r--r-- | src/nvim/winfloat.c | 13 |
3 files changed, 24 insertions, 1 deletions
diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index 040abb1e3f..56a3f1cf23 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -146,7 +146,11 @@ void nvim_tabpage_set_win(Tabpage tabpage, Window win, Error *err) } if (tp == curtab) { - win_enter(wp, true); + try_start(); + win_goto(wp); + if (!try_end(err) && curwin != wp) { + api_set_error(err, kErrorTypeException, "Failed to switch to window %d", win); + } } else if (tp->tp_curwin != wp) { tp->tp_prevwin = tp->tp_curwin; tp->tp_curwin = wp; diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index bb28000719..dab1e4e80b 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -451,6 +451,12 @@ void nvim_win_set_config(Window window, Dict(win_config) *config, Error *err) if (!check_split_disallowed_err(win, err)) { return; // error already set } + // Can't move the cmdwin or its old curwin to a different tabpage. + if ((win == cmdwin_win || win == cmdwin_old_curwin) && parent != NULL + && win_find_tabpage(parent) != win_tp) { + api_set_error(err, kErrorTypeException, "%s", e_cmdwin); + return; + } bool to_split_ok = false; // If we are moving curwin to another tabpage, switch windows *before* we remove it from the diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index 10d8c7ac90..3ddff8aa5a 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -55,6 +55,19 @@ win_T *win_new_float(win_T *wp, bool last, WinConfig fconfig, Error *err) api_set_error(err, kErrorTypeException, "Cannot change window from different tabpage into float"); return NULL; + } else if (cmdwin_win != NULL && !cmdwin_win->w_floating) { + // cmdwin can't become the only non-float. Check for others. + bool other_nonfloat = false; + for (win_T *wp2 = firstwin; wp2 != NULL && !wp2->w_floating; wp2 = wp2->w_next) { + if (wp2 != wp && wp2 != cmdwin_win) { + other_nonfloat = true; + break; + } + } + if (!other_nonfloat) { + api_set_error(err, kErrorTypeException, "%s", e_cmdwin); + return NULL; + } } int dir; winframe_remove(wp, &dir, NULL, NULL); |