diff options
author | Sean Dewar <seandewar@users.noreply.github.com> | 2023-07-24 14:19:01 +0100 |
---|---|---|
committer | Sean Dewar <seandewar@users.noreply.github.com> | 2023-07-26 20:44:46 +0100 |
commit | 472271199e483d3f23d62c272b20c5290eec5474 (patch) | |
tree | 9965e5a35f07a77365d48148c251a52afd2b4d8c | |
parent | 5d921e28c1cc33eced22bbfa823460ca241e3dc1 (diff) | |
download | rneovim-472271199e483d3f23d62c272b20c5290eec5474.tar.gz rneovim-472271199e483d3f23d62c272b20c5290eec5474.tar.bz2 rneovim-472271199e483d3f23d62c272b20c5290eec5474.zip |
feat(api): allow win_hide to close cmdwin or non-previous windows
This aligns its behaviour better with `nvim_win_close`.
Note that `:hide` is actually incapable of closing the cmdwin, unlike `:close`
and `:quit`, so this is a bit of a difference in behaviour.
-rw-r--r-- | runtime/doc/api.txt | 2 | ||||
-rw-r--r-- | src/nvim/api/window.c | 16 | ||||
-rw-r--r-- | src/nvim/window.c | 17 | ||||
-rw-r--r-- | test/functional/api/window_spec.lua | 18 | ||||
-rw-r--r-- | test/functional/vimscript/api_functions_spec.lua | 3 |
5 files changed, 41 insertions, 15 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 1e5b6b0b40..417137c166 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -2897,7 +2897,7 @@ nvim_win_hide({window}) *nvim_win_hide()* or |nvim_win_close()|, which will close the buffer. Attributes: ~ - not allowed when |textlock| is active or in the |cmdwin| + not allowed when |textlock| is active Parameters: ~ • {window} Window handle, or 0 for current window diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 350d934825..f32a7e671d 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -362,10 +362,10 @@ Boolean nvim_win_is_valid(Window window) /// @param[out] err Error details, if any void nvim_win_hide(Window window, Error *err) FUNC_API_SINCE(7) - FUNC_API_TEXTLOCK + FUNC_API_TEXTLOCK_ALLOW_CMDWIN { win_T *win = find_window_by_handle(window, err); - if (!win) { + if (!win || !can_close_in_cmdwin(win, err)) { return; } @@ -397,20 +397,10 @@ void nvim_win_close(Window window, Boolean force, Error *err) FUNC_API_TEXTLOCK_ALLOW_CMDWIN { win_T *win = find_window_by_handle(window, err); - if (!win) { + if (!win || !can_close_in_cmdwin(win, err)) { return; } - if (cmdwin_type != 0) { - if (win == curwin) { - cmdwin_result = Ctrl_C; - return; - } else if (win == cmdwin_old_curwin) { - api_set_error(err, kErrorTypeException, "%s", e_cmdwin); - return; - } - } - tabpage_T *tabpage = win_find_tabpage(win); TryState tstate; try_enter(&tstate); diff --git a/src/nvim/window.c b/src/nvim/window.c index fa7ca53b08..d55bda18c8 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2670,6 +2670,23 @@ static bool can_close_floating_windows(void) return true; } +/// @return true if, considering the cmdwin, `win` is safe to close. +/// If false and `win` is the cmdwin, it is closed; otherwise, `err` is set. +bool can_close_in_cmdwin(win_T *win, Error *err) + FUNC_ATTR_NONNULL_ALL +{ + if (cmdwin_type != 0) { + if (win == curwin) { + cmdwin_result = Ctrl_C; + return false; + } else if (win == cmdwin_old_curwin) { + api_set_error(err, kErrorTypeException, "%s", e_cmdwin); + return false; + } + } + return true; +} + /// Close the possibly last window in a tab page. /// /// @param win window to close diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index 74aaae0c6f..00896a97d8 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -615,6 +615,24 @@ describe('API/win', function() eq({oldwin}, meths.list_wins()) eq({oldbuf}, meths.list_bufs()) end) + it('in the cmdwin', function() + feed('q:') + -- Can close the cmdwin. + meths.win_hide(0) + eq('', funcs.getcmdwintype()) + + local old_win = meths.get_current_win() + local other_win = meths.open_win(0, false, { + relative='win', row=3, col=3, width=12, height=3 + }) + feed('q:') + -- Cannot close the previous window. + eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', + pcall_err(meths.win_hide, old_win)) + -- Can close other windows. + meths.win_hide(other_win) + eq(false, meths.win_is_valid(other_win)) + end) end) describe('text_height', function() diff --git a/test/functional/vimscript/api_functions_spec.lua b/test/functional/vimscript/api_functions_spec.lua index 6548548a9e..0a7e7c1137 100644 --- a/test/functional/vimscript/api_functions_spec.lua +++ b/test/functional/vimscript/api_functions_spec.lua @@ -73,9 +73,10 @@ describe('eval-API', function() -- Some functions checking textlock (usually those that may change the current window or buffer) -- also ought to not be usable in the cmdwin. + local old_win = meths.get_current_win() feed("q:") eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits', - pcall_err(meths.win_hide, 0)) + pcall_err(meths.set_current_win, old_win)) -- But others, like nvim_buf_set_lines(), which just changes text, is OK. curbufmeths.set_lines(0, -1, 1, {"wow!"}) |