aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbutwerenotthereyet <58348703+butwerenotthereyet@users.noreply.github.com>2020-01-09 07:31:16 -0800
committerJustin M. Keyes <justinkz@gmail.com>2020-01-09 07:31:16 -0800
commit29b1a4761a9fadfa9de05cfd9c8aad281fc29791 (patch)
tree13323f88bb92088628c594521b849a054f886d33
parent25afa10f9277dd6148a6abb3d7577c67f479fce2 (diff)
downloadrneovim-29b1a4761a9fadfa9de05cfd9c8aad281fc29791.tar.gz
rneovim-29b1a4761a9fadfa9de05cfd9c8aad281fc29791.tar.bz2
rneovim-29b1a4761a9fadfa9de05cfd9c8aad281fc29791.zip
tabpage: disallow go-to-previous in cmdline-win #11692
After cbc8d72fde4b19176028490934ff7a447afe523c when editing the command in the command editing window (q:, q/, q?) it was possible to switch to the previous tab. Doing so put Nvim in a bad state. Moreover, switching tabs via the other available mechanisms (gt, gT, <C-W>gt, <C-W>gT) is not possible when in the command editing window. Here, the behavior is prevented. It is no longer possible to switch to the previous tab when editing the command in the command editing window. The solution is to share code between gt, gT, and g<Tab>. Specifically, goto_tabpage_lastused now calls through goto_tabpage rather than directly calling goto_tabpage_tp. Doing so works well because all the validation enjoyed by gt and gT is present in goto_tabpage.
-rw-r--r--src/nvim/window.c5
-rw-r--r--test/functional/autocmd/tabnewentered_spec.lua76
2 files changed, 59 insertions, 22 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 8feedf2de6..e913d33de0 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -4113,8 +4113,9 @@ void goto_tabpage_tp(tabpage_T *tp, int trigger_enter_autocmds, int trigger_leav
// Go to the last accessed tab page, if there is one.
void goto_tabpage_lastused(void)
{
- if (valid_tabpage(lastused_tabpage)) {
- goto_tabpage_tp(lastused_tabpage, true, true);
+ int index = tabpage_index(lastused_tabpage);
+ if (index < tabpage_index(NULL)) {
+ goto_tabpage(index);
}
}
diff --git a/test/functional/autocmd/tabnewentered_spec.lua b/test/functional/autocmd/tabnewentered_spec.lua
index 6240db2042..949786d8ff 100644
--- a/test/functional/autocmd/tabnewentered_spec.lua
+++ b/test/functional/autocmd/tabnewentered_spec.lua
@@ -439,32 +439,32 @@ describe('tabpage/previous', function()
does_not_switch_to_previous_after_closing_current_tab('<C-Tab>'))
local function does_not_switch_to_previous_after_entering_operator_pending(characters)
- return function()
- -- Add three tabs for a total of four
- command('tabnew')
- command('tabnew')
- command('tabnew')
+ return function()
+ -- Add three tabs for a total of four
+ command('tabnew')
+ command('tabnew')
+ command('tabnew')
- -- The previous tab is now the third.
- eq(3, eval('tabpagenr(\'#\')'))
+ -- The previous tab is now the third.
+ eq(3, eval('tabpagenr(\'#\')'))
- -- Enter operator pending mode.
- feed('d')
- eq('no', eval('mode(1)'))
+ -- Enter operator pending mode.
+ feed('d')
+ eq('no', eval('mode(1)'))
- -- At this point switching to the previous tab should have no effect
- -- other than leaving operator pending mode.
- feed(characters)
+ -- At this point switching to the previous tab should have no effect
+ -- other than leaving operator pending mode.
+ feed(characters)
- -- Attempting to switch tabs returns us to normal mode.
- eq('n', eval('mode()'))
+ -- Attempting to switch tabs returns us to normal mode.
+ eq('n', eval('mode()'))
- -- The current tab is still the fourth.
- eq(4, eval('tabpagenr()'))
+ -- The current tab is still the fourth.
+ eq(4, eval('tabpagenr()'))
- -- The previous tab is still the third.
- eq(3, eval('tabpagenr(\'#\')'))
- end
+ -- The previous tab is still the third.
+ eq(3, eval('tabpagenr(\'#\')'))
+ end
end
it('does not switch to previous via g<Tab> after entering operator pending',
does_not_switch_to_previous_after_entering_operator_pending('g<Tab>'))
@@ -480,4 +480,40 @@ describe('tabpage/previous', function()
-- does_not_switch_to_previous_after_entering_operator_pending('<C-W>g<Tab>'))
it('does not switch to previous via <C-Tab> after entering operator pending',
does_not_switch_to_previous_after_entering_operator_pending('<C-Tab>'))
+
+ local function cmdline_win_prevents_tab_switch(characters, completion_visible)
+ return function()
+ -- Add three tabs for a total of four
+ command('tabnew')
+ command('tabnew')
+ command('tabnew')
+
+ -- The previous tab is now the third.
+ eq(3, eval('tabpagenr(\'#\')'))
+
+ -- Edit : command line in command-line window
+ feed('q:')
+
+ local cmdline_win_id = eval('win_getid()')
+
+ -- At this point switching to the previous tab should have no effect.
+ feed(characters)
+
+ -- Attempting to switch tabs maintains the current window.
+ eq(cmdline_win_id, eval('win_getid()'))
+ eq(completion_visible, eval('complete_info().pum_visible'))
+
+ -- The current tab is still the fourth.
+ eq(4, eval('tabpagenr()'))
+
+ -- The previous tab is still the third.
+ eq(3, eval('tabpagenr(\'#\')'))
+ end
+ end
+ it('cmdline-win prevents tab switch via g<Tab>',
+ cmdline_win_prevents_tab_switch('g<Tab>', 0))
+ it('cmdline-win prevents tab switch via <C-W>g<Tab>',
+ cmdline_win_prevents_tab_switch('<C-W>g<Tab>', 1))
+ it('cmdline-win prevents tab switch via <C-Tab>',
+ cmdline_win_prevents_tab_switch('<C-Tab>', 0))
end)