aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/eval.c7
-rw-r--r--src/nvim/ex_docmd.c9
-rw-r--r--src/nvim/ex_getln.c2
-rw-r--r--src/nvim/memory.c3
-rw-r--r--src/nvim/testdir/test_cmdline.vim12
-rw-r--r--src/nvim/window.c16
6 files changed, 39 insertions, 10 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 18b9039d60..b2ce15fd87 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -3257,9 +3257,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
}
// b: variables
- // In cmdwin, the alternative buffer should be used.
- hashtab_T *ht
- = is_in_cmdwin() ? &prevwin->w_buffer->b_vars->dv_hashtab : &curbuf->b_vars->dv_hashtab;
+ const hashtab_T *ht = &prevwin_curwin()->w_buffer->b_vars->dv_hashtab;
if (bdone < ht->ht_used) {
if (bdone++ == 0) {
hi = ht->ht_array;
@@ -3273,8 +3271,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
}
// w: variables
- // In cmdwin, the alternative window should be used.
- ht = is_in_cmdwin() ? &prevwin->w_vars->dv_hashtab : &curwin->w_vars->dv_hashtab;
+ ht = &prevwin_curwin()->w_vars->dv_hashtab;
if (wdone < ht->ht_used) {
if (wdone++ == 0) {
hi = ht->ht_array;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 63dc1e539e..6bd465e6ee 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -2704,7 +2704,7 @@ static char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, int *
// only full match global is accepted.
// Look for buffer-local user commands first, then global ones.
- gap = is_in_cmdwin() ? &prevwin->w_buffer->b_ucmds : &curbuf->b_ucmds;
+ gap = &prevwin_curwin()->w_buffer->b_ucmds;
for (;;) {
for (j = 0; j < gap->ga_len; j++) {
uc = USER_CMD_GA(gap, j);
@@ -5378,7 +5378,7 @@ static void uc_list(char_u *name, size_t name_len)
uint32_t a;
// In cmdwin, the alternative buffer should be used.
- garray_T *gap = is_in_cmdwin() ? &prevwin->w_buffer->b_ucmds : &curbuf->b_ucmds;
+ const garray_T *gap = &prevwin_curwin()->w_buffer->b_ucmds;
for (;;) {
for (i = 0; i < gap->ga_len; i++) {
cmd = USER_CMD_GA(gap, i);
@@ -6357,7 +6357,7 @@ char_u *get_user_commands(expand_T *xp FUNC_ATTR_UNUSED, int idx)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
// In cmdwin, the alternative buffer should be used.
- const buf_T *const buf = is_in_cmdwin() ? prevwin->w_buffer : curbuf;
+ const buf_T *const buf = prevwin_curwin()->w_buffer;
if (idx < buf->b_ucmds.ga_len) {
return USER_CMD_GA(&buf->b_ucmds, idx)->uc_name;
@@ -6379,7 +6379,8 @@ static char_u *get_user_command_name(int idx, int cmdidx)
}
if (cmdidx == CMD_USER_BUF) {
// In cmdwin, the alternative buffer should be used.
- buf_T *buf = is_in_cmdwin() ? prevwin->w_buffer : curbuf;
+ const buf_T *const buf = prevwin_curwin()->w_buffer;
+
if (idx < buf->b_ucmds.ga_len) {
return USER_CMD_GA(&buf->b_ucmds, idx)->uc_name;
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 30287cd6f2..f52f3afe7d 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -6589,7 +6589,7 @@ static int open_cmdwin(void)
/// @return true if in the cmdwin, not editing the command line.
bool is_in_cmdwin(void)
- FUNC_ATTR_PURE
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
return cmdwin_type != 0 && get_cmdline_type() == NUL;
}
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index d68ca6b62e..373693a6fe 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -575,6 +575,9 @@ void free_all_mem(void)
// Don't want to trigger autocommands from here on.
block_autocmds();
+ // Ensure cmdline window doesn't prevent closing tabs and windows.
+ cmdwin_type = 0;
+
// Close all tabs and windows. Reset 'equalalways' to avoid redraws.
p_ea = false;
if (first_tabpage->tp_next != NULL) {
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index ff4cbe544c..c589d941da 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -1123,6 +1123,18 @@ func Test_cmdlineclear_tabenter()
call delete('XtestCmdlineClearTabenter')
endfunc
+func Test_cmdwin_tabpage()
+ tabedit
+ " v8.2.1919 isn't ported yet, so E492 is thrown after E11 here.
+ " v8.2.1183 also isn't ported yet, so we also can't assert E11 directly.
+ " For now, assert E11 and E492 seperately. When v8.2.1183 is ported, the
+ " assert for E492 will fail and this workaround should be removed.
+ " call assert_fails("silent norm q/g :I\<Esc>", 'E11:')
+ call assert_fails("silent norm q/g ", 'E11:')
+ call assert_fails("silent norm q/g :I\<Esc>", 'E492:')
+ tabclose!
+endfunc
+
" test that ";" works to find a match at the start of the first line
func Test_zero_line_search()
new
diff --git a/src/nvim/window.c b/src/nvim/window.c
index d659f60e66..5878a6ba0b 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -73,6 +73,15 @@ typedef enum {
static char *m_onlyone = N_("Already only one window");
+/// @return the current window, unless in the cmdline window and "prevwin" is
+/// set, then return "prevwin".
+win_T *prevwin_curwin(void)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ // In cmdwin, the alternative buffer should be used.
+ return is_in_cmdwin() && prevwin != NULL ? prevwin : curwin;
+}
+
/// all CTRL-W window commands are handled here, called from normal_cmd().
///
/// @param xchar extra char from ":wincmd gx" or NUL
@@ -3857,6 +3866,11 @@ int win_new_tabpage(int after, char_u *filename)
tabpage_T *newtp;
int n;
+ if (cmdwin_type != 0) {
+ emsg(_(e_cmdwin));
+ return FAIL;
+ }
+
newtp = alloc_tabpage();
// Remember the current windows in this Tab page.
@@ -4255,6 +4269,8 @@ void goto_tabpage(int n)
/// @param trigger_leave_autocmds when true trigger *Leave autocommands.
void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, bool trigger_leave_autocmds)
{
+ CHECK_CMDWIN;
+
// Don't repeat a message in another tab page.
set_keep_msg(NULL, 0);