mirror of
https://github.com/neovim/neovim.git
synced 2025-10-07 02:16:31 +00:00
tabpage: track last-used tabpage #11626
In a multi-window scenario, it is possible to return focus to the last accessed window via n_CTRL-W_p. However, in the case of a multi-tab scenario, there was previously no way to return focus to the last accessed *tab*. Here, that ability is added via n_g<tab>. Additionally, the index of the previous tab is exposed via tabpagenr('#'), mirroring the existing functionality of winnr('#').
This commit is contained in:

committed by
Justin M. Keyes

parent
2c62b2fc56
commit
cbc8d72fde
@@ -1,5 +1,13 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq
|
||||
|
||||
local clear = helpers.clear
|
||||
local command = helpers.command
|
||||
local dedent = helpers.dedent
|
||||
local eval = helpers.eval
|
||||
local eq = helpers.eq
|
||||
local feed = helpers.feed
|
||||
local nvim = helpers.nvim
|
||||
local redir_exec = helpers.redir_exec
|
||||
|
||||
describe('TabNewEntered', function()
|
||||
describe('au TabNewEntered', function()
|
||||
@@ -29,3 +37,447 @@ describe('TabNewEntered', function()
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('TabEnter', function()
|
||||
before_each(clear)
|
||||
it('has correct previous tab when entering any new tab', function()
|
||||
command('augroup TEMP')
|
||||
nvim('command', 'au! TabEnter * echom "tabenter:".tabpagenr().":".tabpagenr(\'#\')')
|
||||
command('augroup END')
|
||||
eq("tabenter:2:1", nvim('exec', 'tabnew', true))
|
||||
eq("tabenter:3:2", nvim('exec', 'tabnew test.x2', true))
|
||||
command('augroup! TEMP')
|
||||
end)
|
||||
it('has correct previous tab when entering any preexisting tab', function()
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
command('augroup TEMP')
|
||||
nvim('command', 'au! TabEnter * echom "tabenter:".tabpagenr().":".tabpagenr(\'#\')')
|
||||
command('augroup END')
|
||||
eq("tabenter:1:3", nvim('exec', 'tabnext', true))
|
||||
eq("tabenter:2:1", nvim('exec', 'tabnext', true))
|
||||
command('augroup! TEMP')
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('tabpage/previous', function()
|
||||
before_each(clear)
|
||||
local function switches_to_previous_after_new_tab_creation_at_end(characters)
|
||||
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(\'#\')'))
|
||||
|
||||
-- Switch to the previous (third) tab
|
||||
feed(characters)
|
||||
|
||||
eq(dedent([=[
|
||||
|
||||
|
||||
Tab page 1
|
||||
[No Name]
|
||||
Tab page 2
|
||||
[No Name]
|
||||
Tab page 3
|
||||
> [No Name]
|
||||
Tab page 4
|
||||
[No Name]]=]),
|
||||
redir_exec('tabs')
|
||||
)
|
||||
|
||||
-- The previous tab is now the fourth.
|
||||
eq(4, eval('tabpagenr(\'#\')'))
|
||||
end
|
||||
end
|
||||
it('switches to previous via g<Tab> after new tab creation at end',
|
||||
switches_to_previous_after_new_tab_creation_at_end('g<Tab>'))
|
||||
it('switches to previous via <C-W>g<Tab>. after new tab creation at end', switches_to_previous_after_new_tab_creation_at_end('<C-W>g<Tab>'))
|
||||
it('switches to previous via <C-Tab>. after new tab creation at end', switches_to_previous_after_new_tab_creation_at_end('<C-Tab>'))
|
||||
|
||||
local function switches_to_previous_after_new_tab_creation_in_middle(characters)
|
||||
return function()
|
||||
-- Add three tabs for a total of four
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
-- Switch to the second tab
|
||||
command('tabnext 2')
|
||||
-- Add a new tab after the second tab
|
||||
command('tabnew')
|
||||
|
||||
-- The previous tab is now the second.
|
||||
eq(2, eval('tabpagenr(\'#\')'))
|
||||
|
||||
-- Switch to the previous (second) tab
|
||||
feed(characters)
|
||||
eq(dedent([=[
|
||||
|
||||
|
||||
Tab page 1
|
||||
[No Name]
|
||||
Tab page 2
|
||||
> [No Name]
|
||||
Tab page 3
|
||||
[No Name]
|
||||
Tab page 4
|
||||
[No Name]
|
||||
Tab page 5
|
||||
[No Name]]=]),
|
||||
redir_exec('tabs')
|
||||
)
|
||||
|
||||
-- The previous tab is now the third.
|
||||
eq(3, eval('tabpagenr(\'#\')'))
|
||||
end
|
||||
end
|
||||
it('switches to previous via g<Tab> after new tab creation in middle',
|
||||
switches_to_previous_after_new_tab_creation_in_middle('g<Tab>'))
|
||||
it('switches to previous via <C-W>g<Tab> after new tab creation in middle',
|
||||
switches_to_previous_after_new_tab_creation_in_middle('<C-W>g<Tab>'))
|
||||
it('switches to previous via <C-Tab> after new tab creation in middle',
|
||||
switches_to_previous_after_new_tab_creation_in_middle('<C-Tab>'))
|
||||
|
||||
local function switches_to_previous_after_switching_to_next_tab(characters)
|
||||
return function()
|
||||
-- Add three tabs for a total of four
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
-- Switch to the next (first) tab
|
||||
command('tabnext')
|
||||
|
||||
-- The previous tab is now the fourth.
|
||||
eq(4, eval('tabpagenr(\'#\')'))
|
||||
|
||||
-- Switch to the previous (fourth) tab
|
||||
feed(characters)
|
||||
|
||||
eq(dedent([=[
|
||||
|
||||
|
||||
Tab page 1
|
||||
[No Name]
|
||||
Tab page 2
|
||||
[No Name]
|
||||
Tab page 3
|
||||
[No Name]
|
||||
Tab page 4
|
||||
> [No Name]]=]),
|
||||
redir_exec('tabs')
|
||||
)
|
||||
|
||||
-- The previous tab is now the first.
|
||||
eq(1, eval('tabpagenr(\'#\')'))
|
||||
end
|
||||
end
|
||||
it('switches to previous via g<Tab> after switching to next tab',
|
||||
switches_to_previous_after_switching_to_next_tab('g<Tab>'))
|
||||
it('switches to previous via <C-W>g<Tab> after switching to next tab',
|
||||
switches_to_previous_after_switching_to_next_tab('<C-W>g<Tab>'))
|
||||
it('switches to previous via <C-Tab> after switching to next tab',
|
||||
switches_to_previous_after_switching_to_next_tab('<C-Tab>'))
|
||||
|
||||
local function switches_to_previous_after_switching_to_last_tab(characters)
|
||||
return function()
|
||||
-- Add three tabs for a total of four
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
-- Switch to the next (first) tab
|
||||
command('tabnext')
|
||||
-- Switch to the last (fourth) tab.
|
||||
command('tablast')
|
||||
|
||||
-- The previous tab is now the second.
|
||||
eq(1, eval('tabpagenr(\'#\')'))
|
||||
|
||||
-- Switch to the previous (second) tab
|
||||
feed(characters)
|
||||
|
||||
eq(dedent([=[
|
||||
|
||||
|
||||
Tab page 1
|
||||
> [No Name]
|
||||
Tab page 2
|
||||
[No Name]
|
||||
Tab page 3
|
||||
[No Name]
|
||||
Tab page 4
|
||||
[No Name]]=]),
|
||||
redir_exec('tabs')
|
||||
)
|
||||
|
||||
-- The previous tab is now the fourth.
|
||||
eq(4, eval('tabpagenr(\'#\')'))
|
||||
end
|
||||
end
|
||||
it('switches to previous after switching to last tab',
|
||||
switches_to_previous_after_switching_to_last_tab('g<Tab>'))
|
||||
it('switches to previous after switching to last tab',
|
||||
switches_to_previous_after_switching_to_last_tab('<C-W>g<Tab>'))
|
||||
it('switches to previous after switching to last tab',
|
||||
switches_to_previous_after_switching_to_last_tab('<C-Tab>'))
|
||||
|
||||
local function switches_to_previous_after_switching_to_previous_tab(characters)
|
||||
return function()
|
||||
-- Add three tabs for a total of four
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
-- Switch to the previous (third) tab
|
||||
command('tabprevious')
|
||||
|
||||
-- The previous tab is now the fourth.
|
||||
eq(4, eval('tabpagenr(\'#\')'))
|
||||
|
||||
-- Switch to the previous (fourth) tab
|
||||
feed(characters)
|
||||
|
||||
eq(dedent([=[
|
||||
|
||||
|
||||
Tab page 1
|
||||
[No Name]
|
||||
Tab page 2
|
||||
[No Name]
|
||||
Tab page 3
|
||||
[No Name]
|
||||
Tab page 4
|
||||
> [No Name]]=]),
|
||||
redir_exec('tabs')
|
||||
)
|
||||
|
||||
-- The previous tab is now the third.
|
||||
eq(3, eval('tabpagenr(\'#\')'))
|
||||
end
|
||||
end
|
||||
it('switches to previous via g<Tab> after switching to previous tab',
|
||||
switches_to_previous_after_switching_to_previous_tab('g<Tab>'))
|
||||
it('switches to previous via <C-W>g<Tab> after switching to previous tab',
|
||||
switches_to_previous_after_switching_to_previous_tab('<C-W>g<Tab>'))
|
||||
it('switches to previous via <C-Tab> after switching to previous tab',
|
||||
switches_to_previous_after_switching_to_previous_tab('<C-Tab>'))
|
||||
|
||||
local function switches_to_previous_after_switching_to_first_tab(characters)
|
||||
return function()
|
||||
-- Add three tabs for a total of four
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
-- Switch to the previous (third) tab
|
||||
command('tabprevious')
|
||||
-- Switch to the first tab
|
||||
command('tabfirst')
|
||||
|
||||
-- The previous tab is now the third.
|
||||
eq(3, eval('tabpagenr(\'#\')'))
|
||||
|
||||
-- Switch to the previous (third) tab
|
||||
feed(characters)
|
||||
|
||||
eq(dedent([=[
|
||||
|
||||
|
||||
Tab page 1
|
||||
[No Name]
|
||||
Tab page 2
|
||||
[No Name]
|
||||
Tab page 3
|
||||
> [No Name]
|
||||
Tab page 4
|
||||
[No Name]]=]),
|
||||
redir_exec('tabs')
|
||||
)
|
||||
|
||||
-- The previous tab is now the first.
|
||||
eq(1, eval('tabpagenr(\'#\')'))
|
||||
end
|
||||
end
|
||||
it('switches to previous via g<Tab> after switching to first tab',
|
||||
switches_to_previous_after_switching_to_first_tab('g<Tab>'))
|
||||
it('switches to previous via <C-W>g<Tab> after switching to first tab',
|
||||
switches_to_previous_after_switching_to_first_tab('<C-W>g<Tab>'))
|
||||
it('switches to previous via <C-Tab> after switching to first tab',
|
||||
switches_to_previous_after_switching_to_first_tab('<C-Tab>'))
|
||||
|
||||
local function switches_to_previous_after_numbered_tab_switch(characters)
|
||||
return function()
|
||||
-- Add three tabs for a total of four
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
-- Switch to the second tab
|
||||
command('tabnext 2')
|
||||
|
||||
-- The previous tab is now the fourth.
|
||||
eq(4, eval('tabpagenr(\'#\')'))
|
||||
|
||||
-- Switch to the previous (fourth) tab
|
||||
feed(characters)
|
||||
|
||||
eq(dedent([=[
|
||||
|
||||
|
||||
Tab page 1
|
||||
[No Name]
|
||||
Tab page 2
|
||||
[No Name]
|
||||
Tab page 3
|
||||
[No Name]
|
||||
Tab page 4
|
||||
> [No Name]]=]),
|
||||
redir_exec('tabs')
|
||||
)
|
||||
|
||||
-- The previous tab is now the second.
|
||||
eq(2, eval('tabpagenr(\'#\')'))
|
||||
end
|
||||
end
|
||||
it('switches to previous via g<Tab> after numbered tab switch',
|
||||
switches_to_previous_after_numbered_tab_switch('g<Tab>'))
|
||||
it('switches to previous via <C-W>g<Tab> after numbered tab switch',
|
||||
switches_to_previous_after_numbered_tab_switch('<C-W>g<Tab>'))
|
||||
it('switches to previous via <C-Tab> after numbered tab switch',
|
||||
switches_to_previous_after_numbered_tab_switch('<C-Tab>'))
|
||||
|
||||
local function switches_to_previous_after_switching_to_previous(characters1, characters2)
|
||||
return function()
|
||||
-- Add three tabs for a total of four
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
-- Switch to the second tab
|
||||
command('tabnext 2')
|
||||
-- Switch to the previous (fourth) tab
|
||||
feed(characters1)
|
||||
|
||||
-- The previous tab is now the second.
|
||||
eq(2, eval('tabpagenr(\'#\')'))
|
||||
|
||||
-- Switch to the previous (second) tab
|
||||
feed(characters2)
|
||||
|
||||
eq(dedent([=[
|
||||
|
||||
|
||||
Tab page 1
|
||||
[No Name]
|
||||
Tab page 2
|
||||
> [No Name]
|
||||
Tab page 3
|
||||
[No Name]
|
||||
Tab page 4
|
||||
[No Name]]=]),
|
||||
redir_exec('tabs')
|
||||
)
|
||||
|
||||
-- The previous tab is now the fourth.
|
||||
eq(4, eval('tabpagenr(\'#\')'))
|
||||
end
|
||||
end
|
||||
it('switches to previous via g<Tab> after switching to previous via g<Tab>',
|
||||
switches_to_previous_after_switching_to_previous('g<Tab>', 'g<Tab>'))
|
||||
it('switches to previous via <C-W>g<Tab> after switching to previous via g<Tab>',
|
||||
switches_to_previous_after_switching_to_previous('g<Tab>', '<C-W>g<Tab>'))
|
||||
it('switches to previous via <C-Tab> after switching to previous via g<Tab>',
|
||||
switches_to_previous_after_switching_to_previous('g<Tab>', '<C-Tab>'))
|
||||
it('switches to previous via g<Tab> after switching to previous via <C-W>g<Tab>',
|
||||
switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', 'g<Tab>'))
|
||||
it('switches to previous via <C-W>g<Tab> after switching to previous via <C-W>g<Tab>',
|
||||
switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', '<C-W>g<Tab>'))
|
||||
it('switches to previous via <C-Tab> after switching to previous via <C-W>g<Tab>',
|
||||
switches_to_previous_after_switching_to_previous('<C-W>g<Tab>', '<C-Tab>'))
|
||||
it('switches to previous via g<Tab> after switching to previous via <C-Tab>',
|
||||
switches_to_previous_after_switching_to_previous('<C-Tab>', 'g<Tab>'))
|
||||
it('switches to previous via <C-W>g<Tab> after switching to previous via <C-Tab>',
|
||||
switches_to_previous_after_switching_to_previous('<C-Tab>', '<C-W>g<Tab>'))
|
||||
it('switches to previous via <C-Tab> after switching to previous via <C-Tab>',
|
||||
switches_to_previous_after_switching_to_previous('<C-Tab>', '<C-Tab>'))
|
||||
|
||||
local function does_not_switch_to_previous_after_closing_current_tab(characters)
|
||||
return function()
|
||||
-- Add three tabs for a total of four
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
command('tabnew')
|
||||
-- Close the current (fourth tab)
|
||||
command('wincmd c')
|
||||
|
||||
-- The previous tab is now the "zeroth" -- there isn't one.
|
||||
eq(0, eval('tabpagenr(\'#\')'))
|
||||
|
||||
-- At this point, switching to the "previous" (i.e. fourth) tab would mean
|
||||
-- switching to either a dangling or a null pointer.
|
||||
feed(characters)
|
||||
|
||||
eq(dedent([=[
|
||||
|
||||
|
||||
Tab page 1
|
||||
[No Name]
|
||||
Tab page 2
|
||||
[No Name]
|
||||
Tab page 3
|
||||
> [No Name]]=]),
|
||||
redir_exec('tabs')
|
||||
)
|
||||
|
||||
-- The previous tab is now the "zero".
|
||||
eq(0, eval('tabpagenr(\'#\')'))
|
||||
end
|
||||
end
|
||||
it('does not switch to previous via g<Tab> after closing current tab',
|
||||
does_not_switch_to_previous_after_closing_current_tab('g<Tab>'))
|
||||
it('does not switch to previous via <C-W>g<Tab> after closing current tab',
|
||||
does_not_switch_to_previous_after_closing_current_tab('<C-W>g<Tab>'))
|
||||
it('does not switch to previous via <C-Tab> after closing current tab',
|
||||
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')
|
||||
|
||||
-- The previous tab is now the third.
|
||||
eq(3, eval('tabpagenr(\'#\')'))
|
||||
|
||||
-- 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)
|
||||
|
||||
-- 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 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>'))
|
||||
-- NOTE: When in operator pending mode, attempting to switch to previous has
|
||||
-- the following effect:
|
||||
-- - Ctrl-W exits operator pending mode
|
||||
-- - g<Tab> switches to the previous tab
|
||||
-- In other words, the effect of "<C-W>g<Tab>" is to switch to the
|
||||
-- previous tab even from operator pending mode, but only thanks to the
|
||||
-- fact that the suffix after "<C-W>" in "<C-W>g<Tab>" just happens to
|
||||
-- be the same as the normal mode command to switch to the previous tab.
|
||||
-- it('does not switch to previous via <C-W>g<Tab> after entering operator pending',
|
||||
-- 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>'))
|
||||
end)
|
||||
|
Reference in New Issue
Block a user