vim-patch:8.0.0259

Problem:    Tab commands do not handle count correctly. (Ken Hamada)
Solution:   Add ADDR_TABS_RELATIVE. (Hirohito Higashi)

2f72c70657
This commit is contained in:
Justin M. Keyes 2017-03-21 16:22:04 +01:00
parent 386a5f379b
commit 0f3afdaa1b
5 changed files with 448 additions and 128 deletions

View File

@ -34,7 +34,8 @@ local ADDR_ARGUMENTS = 2
local ADDR_LOADED_BUFFERS = 3 local ADDR_LOADED_BUFFERS = 3
local ADDR_BUFFERS = 4 local ADDR_BUFFERS = 4
local ADDR_TABS = 5 local ADDR_TABS = 5
local ADDR_QUICKFIX = 6 local ADDR_TABS_RELATIVE = 6
local ADDR_QUICKFIX = 7
local ADDR_OTHER = 99 local ADDR_OTHER = 99
-- The following table is described in ex_cmds_defs.h file. -- The following table is described in ex_cmds_defs.h file.
@ -2650,12 +2651,12 @@ return {
{ {
command='tab', command='tab',
flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM),
addr_type=ADDR_LINES, addr_type=ADDR_TABS,
func='ex_wrongmodifier', func='ex_wrongmodifier',
}, },
{ {
command='tabclose', command='tabclose',
flags=bit.bor(RANGE, NOTADR, COUNT, BANG, TRLBAR, CMDWIN), flags=bit.bor(BANG, RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN),
addr_type=ADDR_TABS, addr_type=ADDR_TABS,
func='ex_tabclose', func='ex_tabclose',
}, },
@ -2680,7 +2681,7 @@ return {
{ {
command='tabfirst', command='tabfirst',
flags=bit.bor(TRLBAR), flags=bit.bor(TRLBAR),
addr_type=ADDR_LINES, addr_type=ADDR_TABS,
func='ex_tabnext', func='ex_tabnext',
}, },
{ {
@ -2692,13 +2693,13 @@ return {
{ {
command='tablast', command='tablast',
flags=bit.bor(TRLBAR), flags=bit.bor(TRLBAR),
addr_type=ADDR_LINES, addr_type=ADDR_TABS,
func='ex_tabnext', func='ex_tabnext',
}, },
{ {
command='tabnext', command='tabnext',
flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
addr_type=ADDR_LINES, addr_type=ADDR_TABS,
func='ex_tabnext', func='ex_tabnext',
}, },
{ {
@ -2709,32 +2710,32 @@ return {
}, },
{ {
command='tabonly', command='tabonly',
flags=bit.bor(BANG, RANGE, NOTADR, TRLBAR, CMDWIN), flags=bit.bor(BANG, RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN),
addr_type=ADDR_TABS, addr_type=ADDR_TABS,
func='ex_tabonly', func='ex_tabonly',
}, },
{ {
command='tabprevious', command='tabprevious',
flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
addr_type=ADDR_LINES, addr_type=ADDR_TABS_RELATIVE,
func='ex_tabnext', func='ex_tabnext',
}, },
{ {
command='tabNext', command='tabNext',
flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
addr_type=ADDR_LINES, addr_type=ADDR_TABS_RELATIVE,
func='ex_tabnext', func='ex_tabnext',
}, },
{ {
command='tabrewind', command='tabrewind',
flags=bit.bor(TRLBAR), flags=bit.bor(TRLBAR),
addr_type=ADDR_LINES, addr_type=ADDR_TABS,
func='ex_tabnext', func='ex_tabnext',
}, },
{ {
command='tabs', command='tabs',
flags=bit.bor(TRLBAR, CMDWIN), flags=bit.bor(TRLBAR, CMDWIN),
addr_type=ADDR_LINES, addr_type=ADDR_TABS,
func='ex_tabs', func='ex_tabs',
}, },
{ {

View File

@ -72,7 +72,8 @@
#define ADDR_LOADED_BUFFERS 3 #define ADDR_LOADED_BUFFERS 3
#define ADDR_BUFFERS 4 #define ADDR_BUFFERS 4
#define ADDR_TABS 5 #define ADDR_TABS 5
#define ADDR_QUICKFIX 6 #define ADDR_TABS_RELATIVE 6 // Tab page that only relative
#define ADDR_QUICKFIX 7
#define ADDR_OTHER 99 #define ADDR_OTHER 99
typedef struct exarg exarg_T; typedef struct exarg exarg_T;

View File

@ -1522,8 +1522,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 = curwin->w_cursor.lnum; ea.line2 = curwin->w_cursor.lnum;
break; break;
case ADDR_WINDOWS: case ADDR_WINDOWS:
lnum = CURRENT_WIN_NR; ea.line2 = CURRENT_WIN_NR;
ea.line2 = lnum;
break; break;
case ADDR_ARGUMENTS: case ADDR_ARGUMENTS:
ea.line2 = curwin->w_arg_idx + 1; ea.line2 = curwin->w_arg_idx + 1;
@ -1536,8 +1535,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 = curbuf->b_fnum; ea.line2 = curbuf->b_fnum;
break; break;
case ADDR_TABS: case ADDR_TABS:
lnum = CURRENT_TAB_NR; ea.line2 = CURRENT_TAB_NR;
ea.line2 = lnum; break;
case ADDR_TABS_RELATIVE:
ea.line2 = 1;
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
ea.line2 = qf_get_cur_valid_idx(&ea); ea.line2 = qf_get_cur_valid_idx(&ea);
@ -1587,6 +1588,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
goto doend; goto doend;
} }
break; break;
case ADDR_TABS_RELATIVE:
errormsg = (char_u *)_(e_invrange);
goto doend;
break;
case ADDR_ARGUMENTS: case ADDR_ARGUMENTS:
if (ARGCOUNT == 0) { if (ARGCOUNT == 0) {
ea.line1 = ea.line2 = 0; ea.line1 = ea.line2 = 0;
@ -1973,6 +1978,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
case ADDR_TABS: case ADDR_TABS:
ea.line2 = LAST_TAB_NR; ea.line2 = LAST_TAB_NR;
break; break;
case ADDR_TABS_RELATIVE:
ea.line2 = 1;
break;
case ADDR_ARGUMENTS: case ADDR_ARGUMENTS:
if (ARGCOUNT == 0) { if (ARGCOUNT == 0) {
ea.line1 = ea.line2 = 0; ea.line1 = ea.line2 = 0;
@ -2028,11 +2036,11 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line1 = ea.line2; ea.line1 = ea.line2;
ea.line2 += n - 1; ea.line2 += n - 1;
++ea.addr_count; ++ea.addr_count;
/* // Be vi compatible: no error message for out of range.
* Be vi compatible: no error message for out of range. if (ea.addr_type == ADDR_LINES
*/ && ea.line2 > curbuf->b_ml.ml_line_count) {
if (ea.line2 > curbuf->b_ml.ml_line_count)
ea.line2 = curbuf->b_ml.ml_line_count; ea.line2 = curbuf->b_ml.ml_line_count;
}
} }
} }
@ -3459,6 +3467,11 @@ static linenr_T get_address(exarg_T *eap,
case ADDR_TABS: case ADDR_TABS:
lnum = CURRENT_TAB_NR; lnum = CURRENT_TAB_NR;
break; break;
case ADDR_TABS_RELATIVE:
EMSG(_(e_invrange));
cmd = NULL;
goto error;
break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
lnum = qf_get_cur_valid_idx(eap); lnum = qf_get_cur_valid_idx(eap);
break; break;
@ -3493,6 +3506,11 @@ static linenr_T get_address(exarg_T *eap,
case ADDR_TABS: case ADDR_TABS:
lnum = LAST_TAB_NR; lnum = LAST_TAB_NR;
break; break;
case ADDR_TABS_RELATIVE:
EMSG(_(e_invrange));
cmd = NULL;
goto error;
break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
lnum = qf_get_size(eap); lnum = qf_get_size(eap);
if (lnum == 0) { if (lnum == 0) {
@ -3641,6 +3659,9 @@ static linenr_T get_address(exarg_T *eap,
case ADDR_TABS: case ADDR_TABS:
lnum = CURRENT_TAB_NR; lnum = CURRENT_TAB_NR;
break; break;
case ADDR_TABS_RELATIVE:
lnum = 1;
break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
lnum = qf_get_cur_valid_idx(eap); lnum = qf_get_cur_valid_idx(eap);
break; break;
@ -3655,7 +3676,12 @@ static linenr_T get_address(exarg_T *eap,
n = 1; n = 1;
else else
n = getdigits(&cmd); n = getdigits(&cmd);
if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS) {
if (addr_type == ADDR_TABS_RELATIVE) {
EMSG(_(e_invrange));
cmd = NULL;
goto error;
} else if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS) {
lnum = compute_buffer_local_count( lnum = compute_buffer_local_count(
addr_type, lnum, (i == '-') ? -1 * n : n); addr_type, lnum, (i == '-') ? -1 * n : n);
} else { } else {
@ -3777,6 +3803,9 @@ static char_u *invalid_range(exarg_T *eap)
return (char_u *)_(e_invrange); return (char_u *)_(e_invrange);
} }
break; break;
case ADDR_TABS_RELATIVE:
// Do nothing
break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
assert(eap->line2 >= 0); assert(eap->line2 >= 0);
if (eap->line2 != 1 && (size_t)eap->line2 > qf_get_size(eap)) { if (eap->line2 != 1 && (size_t)eap->line2 > qf_get_size(eap)) {
@ -4285,6 +4314,104 @@ static int getargopt(exarg_T *eap)
return OK; return OK;
} }
/*
* Handle the argument for a tabpage related ex command.
* Returns a tabpage number.
* When an error is encountered then eap->errmsg is set.
*/
static int
get_tabpage_arg(exarg_T *eap)
{
int tab_number;
int unaccept_arg0 = (eap->cmdidx == CMD_tabmove) ? 0 : 1;
if (eap->arg && *eap->arg != NUL)
{
char_u *p = eap->arg;
char_u *p_save;
int relative = 0; /* argument +N/-N means: go to N places to the
* right/left relative to the current position. */
if (*p == '-')
{
relative = -1;
p++;
}
else if (*p == '+')
{
relative = 1;
p++;
}
p_save = p;
tab_number = getdigits(&p);
if (relative == 0)
{
if (STRCMP(p, "$") == 0)
tab_number = LAST_TAB_NR;
else if (p == p_save || *p_save == '-' || *p != NUL
|| tab_number > LAST_TAB_NR)
{
/* No numbers as argument. */
eap->errmsg = e_invarg;
goto theend;
}
}
else
{
if (*p_save == NUL)
tab_number = 1;
else if (p == p_save || *p_save == '-' || *p != NUL
|| tab_number == 0)
{
/* No numbers as argument. */
eap->errmsg = e_invarg;
goto theend;
}
tab_number = tab_number * relative + tabpage_index(curtab);
if (!unaccept_arg0 && relative == -1)
--tab_number;
}
if (tab_number < unaccept_arg0 || tab_number > LAST_TAB_NR)
eap->errmsg = e_invarg;
}
else if (eap->addr_count > 0)
{
if (unaccept_arg0 && eap->line2 == 0)
eap->errmsg = e_invrange;
else
{
tab_number = eap->line2;
if (!unaccept_arg0 && **eap->cmdlinep == '-')
{
--tab_number;
if (tab_number < unaccept_arg0)
eap->errmsg = e_invarg;
}
}
}
else
{
switch (eap->cmdidx)
{
case CMD_tabnext:
tab_number = tabpage_index(curtab) + 1;
if (tab_number > LAST_TAB_NR)
tab_number = 1;
break;
case CMD_tabmove:
tab_number = LAST_TAB_NR;
break;
default:
tab_number = tabpage_index(curtab);
}
}
theend:
return tab_number;
}
/* /*
* ":abbreviate" and friends. * ":abbreviate" and friends.
*/ */
@ -5938,8 +6065,9 @@ static void ex_tabclose(exarg_T *eap)
else if (first_tabpage->tp_next == NULL) else if (first_tabpage->tp_next == NULL)
EMSG(_("E784: Cannot close last tab page")); EMSG(_("E784: Cannot close last tab page"));
else { else {
if (eap->addr_count > 0) { int tab_number = get_tabpage_arg(eap);
tp = find_tabpage((int)eap->line2); if (eap->errmsg == NULL) {
tp = find_tabpage(tab_number);
if (tp == NULL) { if (tp == NULL) {
beep_flush(); beep_flush();
return; return;
@ -5947,44 +6075,43 @@ static void ex_tabclose(exarg_T *eap)
if (tp != curtab) { if (tp != curtab) {
tabpage_close_other(tp, eap->forceit); tabpage_close_other(tp, eap->forceit);
return; return;
} else if (!text_locked() && !curbuf_locked()) {
tabpage_close(eap->forceit);
} }
} }
if (!text_locked()
&& !curbuf_locked()
)
tabpage_close(eap->forceit);
} }
} }
/* /// ":tabonly": close all tab pages except the current one
* ":tabonly": close all tab pages except the current one
*/
static void ex_tabonly(exarg_T *eap) static void ex_tabonly(exarg_T *eap)
{ {
if (cmdwin_type != 0) if (cmdwin_type != 0) {
cmdwin_result = K_IGNORE; cmdwin_result = K_IGNORE;
else if (first_tabpage->tp_next == NULL) } else if (first_tabpage->tp_next == NULL) {
MSG(_("Already only one tab page")); MSG(_("Already only one tab page"));
else { } else {
if (eap->addr_count > 0) int tab_number = get_tabpage_arg(eap);
goto_tabpage(eap->line2); if (eap->errmsg == NULL) {
/* Repeat this up to a 1000 times, because autocommands may mess goto_tabpage(tab_number);
* up the lists. */ // Repeat this up to a 1000 times, because autocommands may
for (int done = 0; done < 1000; ++done) { // mess up the lists.
FOR_ALL_TABS(tp) { for (int done = 0; done < 1000; done++) {
if (tp->tp_topframe != topframe) { FOR_ALL_TABS(tp) {
tabpage_close_other(tp, eap->forceit); if (tp->tp_topframe != topframe) {
/* if we failed to close it quit */ tabpage_close_other(tp, eap->forceit);
if (valid_tabpage(tp)) // if we failed to close it quit
done = 1000; if (valid_tabpage(tp)) {
/* start over, "tp" is now invalid */ done = 1000;
}
// start over, "tp" is now invalid
break;
}
}
assert(first_tabpage);
if (first_tabpage->tp_next == NULL) {
break; break;
} }
} }
assert(first_tabpage);
if (first_tabpage->tp_next == NULL) {
break;
}
} }
} }
} }
@ -6473,6 +6600,8 @@ void tabpage_new(void)
*/ */
static void ex_tabnext(exarg_T *eap) static void ex_tabnext(exarg_T *eap)
{ {
int tab_number;
switch (eap->cmdidx) { switch (eap->cmdidx) {
case CMD_tabfirst: case CMD_tabfirst:
case CMD_tabrewind: case CMD_tabrewind:
@ -6483,10 +6612,34 @@ static void ex_tabnext(exarg_T *eap)
break; break;
case CMD_tabprevious: case CMD_tabprevious:
case CMD_tabNext: case CMD_tabNext:
goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2); if (eap->arg && *eap->arg != NUL) {
char_u *p = eap->arg;
char_u *p_save = p;
tab_number = getdigits(&p);
if (p == p_save || *p_save == '-' || *p != NUL || tab_number == 0) {
// No numbers as argument.
eap->errmsg = e_invarg;
return;
}
} else {
if (eap->addr_count == 0) {
tab_number = 1;
} else {
tab_number = eap->line2;
if (tab_number < 1) {
eap->errmsg = e_invrange;
return;
}
}
}
goto_tabpage(-tab_number);
break; break;
default: /* CMD_tabnext */ default: // CMD_tabnext
goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2); tab_number = get_tabpage_arg(eap);
if (eap->errmsg == NULL) {
goto_tabpage(tab_number);
}
break; break;
} }
} }
@ -6496,53 +6649,10 @@ static void ex_tabnext(exarg_T *eap)
*/ */
static void ex_tabmove(exarg_T *eap) static void ex_tabmove(exarg_T *eap)
{ {
int tab_number; int tab_number = get_tabpage_arg(eap);
if (eap->errmsg == NULL) {
if (eap->arg && *eap->arg != NUL) { tabpage_move(tab_number);
char_u *p = eap->arg;
int relative = 0; /* argument +N/-N means: move N places to the
* right/left relative to the current position. */
if (*eap->arg == '-') {
relative = -1;
p = eap->arg + 1;
} else if (*eap->arg == '+') {
relative = 1;
p = eap->arg + 1;
} else
p = eap->arg;
if (relative == 0) {
if (STRCMP(p, "$") == 0) {
tab_number = LAST_TAB_NR;
} else if (p == skipdigits(p)) {
// No numbers as argument.
eap->errmsg = e_invarg;
return;
} else {
tab_number = getdigits(&p);
}
} else {
if (*p != NUL) {
tab_number = getdigits(&p);
} else {
tab_number = 1;
}
tab_number = tab_number * relative + tabpage_index(curtab);
if (relative == -1) {
--tab_number;
}
}
} else if (eap->addr_count != 0) {
tab_number = eap->line2;
if (**eap->cmdlinep == '-') {
--tab_number;
}
} else {
tab_number = LAST_TAB_NR;
} }
tabpage_move(tab_number);
} }
/* /*

View File

@ -94,10 +94,6 @@ function Test_tabpage()
call assert_equal(7, tabpagenr()) call assert_equal(7, tabpagenr())
tabmove tabmove
call assert_equal(10, tabpagenr()) call assert_equal(10, tabpagenr())
tabmove -20
call assert_equal(1, tabpagenr())
tabmove +20
call assert_equal(10, tabpagenr())
0tabmove 0tabmove
call assert_equal(1, tabpagenr()) call assert_equal(1, tabpagenr())
$tabmove $tabmove
@ -110,7 +106,16 @@ function Test_tabpage()
call assert_equal(4, tabpagenr()) call assert_equal(4, tabpagenr())
7tabmove 5 7tabmove 5
call assert_equal(5, tabpagenr()) call assert_equal(5, tabpagenr())
call assert_fails("99tabmove", 'E16:')
call assert_fails("+99tabmove", 'E16:')
call assert_fails("-99tabmove", 'E16:')
call assert_fails("tabmove foo", 'E474:') call assert_fails("tabmove foo", 'E474:')
call assert_fails("tabmove 99", 'E474:')
call assert_fails("tabmove +99", 'E474:')
call assert_fails("tabmove -99", 'E474:')
call assert_fails("tabmove -3+", 'E474:')
call assert_fails("tabmove $3", 'E474:')
1tabonly!
endfunc endfunc
" Test autocommands " Test autocommands
@ -118,7 +123,6 @@ function Test_tabpage_with_autocmd()
if !has('autocmd') if !has('autocmd')
return return
endif endif
tabonly!
command -nargs=1 -bar C :call add(s:li, '=== ' . <q-args> . ' ===')|<args> command -nargs=1 -bar C :call add(s:li, '=== ' . <q-args> . ' ===')|<args>
augroup TestTabpageGroup augroup TestTabpageGroup
au! au!
@ -183,8 +187,10 @@ function Test_tabpage_with_autocmd()
autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3 autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3
let s:li = [] let s:li = []
C tabnext 3 call assert_equal(3, tabpagenr('$'))
call assert_equal(['=== tabnext 3 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ===', 'BufEnter', '=== tabclose 3 ==='], s:li) C tabnext 2
call assert_equal(2, tabpagenr('$'))
call assert_equal(['=== tabnext 2 ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ==='], s:li)
call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')]) call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')])
delcommand C delcommand C
@ -192,8 +198,7 @@ function Test_tabpage_with_autocmd()
augroup! TabDestructive augroup! TabDestructive
autocmd! TestTabpageGroup autocmd! TestTabpageGroup
augroup! TestTabpageGroup augroup! TestTabpageGroup
tabonly! 1tabonly!
bw!
endfunction endfunction
function Test_tabpage_with_tab_modifier() function Test_tabpage_with_tab_modifier()
@ -224,8 +229,223 @@ function Test_tabpage_with_tab_modifier()
call assert_fails('-99tab help', 'E16:') call assert_fails('-99tab help', 'E16:')
delfunction s:check_tab delfunction s:check_tab
tabonly! 1tabonly!
bw! endfunction
function Check_tab_count(pre_nr, cmd, post_nr)
exec 'tabnext' a:pre_nr
normal! G
exec a:cmd
call assert_equal(a:post_nr, tabpagenr(), a:cmd)
endfunc
" Test for [count] of tabnext
function Test_tabpage_with_tabnext()
for n in range(4)
tabedit
call setline(1, ['', '', '3'])
endfor
call Check_tab_count(1, 'tabnext', 2)
call Check_tab_count(1, '3tabnext', 3)
call Check_tab_count(1, '.tabnext', 1)
call Check_tab_count(1, '.+1tabnext', 2)
call Check_tab_count(2, '+tabnext', 3)
call Check_tab_count(2, '+2tabnext', 4)
call Check_tab_count(4, '-tabnext', 3)
call Check_tab_count(4, '-2tabnext', 2)
call Check_tab_count(3, '$tabnext', 5)
call assert_fails('0tabnext', 'E16:')
call assert_fails('99tabnext', 'E16:')
call assert_fails('+99tabnext', 'E16:')
call assert_fails('-99tabnext', 'E16:')
call Check_tab_count(1, 'tabnext 3', 3)
call Check_tab_count(2, 'tabnext +', 3)
call Check_tab_count(2, 'tabnext +2', 4)
call Check_tab_count(4, 'tabnext -', 3)
call Check_tab_count(4, 'tabnext -2', 2)
call Check_tab_count(3, 'tabnext $', 5)
call assert_fails('tabnext 0', 'E474:')
call assert_fails('tabnext .', 'E474:')
call assert_fails('tabnext -+', 'E474:')
call assert_fails('tabnext +2-', 'E474:')
call assert_fails('tabnext $3', 'E474:')
call assert_fails('tabnext 99', 'E474:')
call assert_fails('tabnext +99', 'E474:')
call assert_fails('tabnext -99', 'E474:')
1tabonly!
endfunction
" Test for [count] of tabprevious
function Test_tabpage_with_tabprevious()
for n in range(5)
tabedit
call setline(1, ['', '', '3'])
endfor
for cmd in ['tabNext', 'tabprevious']
call Check_tab_count(6, cmd, 5)
call Check_tab_count(6, '3' . cmd, 3)
call Check_tab_count(6, '8' . cmd, 4)
call Check_tab_count(6, cmd . ' 3', 3)
call Check_tab_count(6, cmd . ' 8', 4)
for n in range(2)
for c in ['0', '.+3', '+', '+2' , '-', '-2' , '$', '+99', '-99']
if n == 0 " pre count
let entire_cmd = c . cmd
let err_code = 'E16:'
else
let entire_cmd = cmd . ' ' . c
let err_code = 'E474:'
endif
call assert_fails(entire_cmd, err_code)
endfor
endfor
endfor
1tabonly!
endfunction
function s:reconstruct_tabpage_for_test(nr)
let n = (a:nr > 2) ? a:nr - 2 : 1
1tabonly!
0tabedit n0
for n in range(1, n)
exec '$tabedit n' . n
if n == 1
call setline(1, ['', '', '3'])
endif
endfor
endfunc
" Test for [count] of tabclose
function Test_tabpage_with_tabclose()
" pre count
call s:reconstruct_tabpage_for_test(6)
call Check_tab_count(3, 'tabclose!', 3)
call Check_tab_count(1, '3tabclose', 1)
call Check_tab_count(4, '4tabclose', 3)
call Check_tab_count(3, '1tabclose', 2)
call Check_tab_count(2, 'tabclose', 1)
call assert_equal(1, tabpagenr('$'))
call assert_equal('', bufname(''))
call s:reconstruct_tabpage_for_test(6)
call Check_tab_count(2, '$tabclose', 2)
call Check_tab_count(4, '.tabclose', 4)
call Check_tab_count(3, '.+tabclose', 3)
call Check_tab_count(3, '.-2tabclose', 2)
call Check_tab_count(1, '.+1tabclose!', 1)
call assert_equal(1, tabpagenr('$'))
call assert_equal('', bufname(''))
" post count
call s:reconstruct_tabpage_for_test(6)
call Check_tab_count(3, 'tabclose!', 3)
call Check_tab_count(1, 'tabclose 3', 1)
call Check_tab_count(4, 'tabclose 4', 3)
call Check_tab_count(3, 'tabclose 1', 2)
call Check_tab_count(2, 'tabclose', 1)
call assert_equal(1, tabpagenr('$'))
call assert_equal('', bufname(''))
call s:reconstruct_tabpage_for_test(6)
call Check_tab_count(2, 'tabclose $', 2)
call Check_tab_count(4, 'tabclose', 4)
call Check_tab_count(3, 'tabclose +', 3)
call Check_tab_count(3, 'tabclose -2', 2)
call Check_tab_count(1, 'tabclose! +1', 1)
call assert_equal(1, tabpagenr('$'))
call assert_equal('', bufname(''))
call s:reconstruct_tabpage_for_test(6)
for n in range(2)
for c in ['0', '$3', '99', '+99', '-99']
if n == 0 " pre count
let entire_cmd = c . 'tabclose'
let err_code = 'E16:'
else
let entire_cmd = 'tabclose ' . c
let err_code = 'E474:'
endif
call assert_fails(entire_cmd, err_code)
call assert_equal(6, tabpagenr('$'))
endfor
endfor
call assert_fails('3tabclose', 'E37:')
call assert_fails('tabclose 3', 'E37:')
call assert_fails('tabclose -+', 'E474:')
call assert_fails('tabclose +2-', 'E474:')
call assert_equal(6, tabpagenr('$'))
1tabonly!
endfunction
" Test for [count] of tabonly
function Test_tabpage_with_tabonly()
" Test for the normal behavior (pre count only)
let tc = [ [4, '.', '!'], [2, '.+', ''], [3, '.-2', '!'], [1, '.+1', '!'] ]
for c in tc
call s:reconstruct_tabpage_for_test(6)
let entire_cmd = c[1] . 'tabonly' . c[2]
call Check_tab_count(c[0], entire_cmd, 1)
call assert_equal(1, tabpagenr('$'))
endfor
" Test for the normal behavior
let tc2 = [ [3, '', ''], [1, '3', ''], [4, '4', '!'], [3, '1', '!'],
\ [2, '', '!'],
\ [2, '$', '!'], [3, '+', '!'], [3, '-2', '!'], [3, '+1', '!']
\ ]
for n in range(2)
for c in tc2
call s:reconstruct_tabpage_for_test(6)
if n == 0 " pre count
let entire_cmd = c[1] . 'tabonly' . c[2]
else
let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
endif
call Check_tab_count(c[0], entire_cmd, 1)
call assert_equal(1, tabpagenr('$'))
endfor
endfor
" Test for the error behavior
for n in range(2)
for c in ['0', '$3', '99', '+99', '-99']
call s:reconstruct_tabpage_for_test(6)
if n == 0 " pre count
let entire_cmd = c . 'tabonly'
let err_code = 'E16:'
else
let entire_cmd = 'tabonly ' . c
let err_code = 'E474:'
endif
call assert_fails(entire_cmd, err_code)
call assert_equal(6, tabpagenr('$'))
endfor
endfor
" Test for the error behavior (post count only)
for c in tc
call s:reconstruct_tabpage_for_test(6)
let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
let err_code = 'E474:'
call assert_fails(entire_cmd, err_code)
call assert_equal(6, tabpagenr('$'))
endfor
call assert_fails('tabonly -+', 'E474:')
call assert_fails('tabonly +2-', 'E474:')
call assert_equal(6, tabpagenr('$'))
1tabonly!
new
only!
endfunction endfunction
func Test_tabnext_on_buf_unload1() func Test_tabnext_on_buf_unload1()

View File

@ -99,10 +99,6 @@ describe('tab pages', function()
eq(7, eval('tabpagenr()')) eq(7, eval('tabpagenr()'))
execute('tabmove') execute('tabmove')
eq(10, eval('tabpagenr()')) eq(10, eval('tabpagenr()'))
execute('tabmove -20')
eq(1, eval('tabpagenr()'))
execute('tabmove +20')
eq(10, eval('tabpagenr()'))
execute('0tabmove') execute('0tabmove')
eq(1, eval('tabpagenr()')) eq(1, eval('tabpagenr()'))
execute('$tabmove') execute('$tabmove')
@ -172,7 +168,7 @@ describe('tab pages', function()
C tabnext 1 C tabnext 1
autocmd TabDestructive TabEnter * nested autocmd TabDestructive TabEnter * nested
\ :C tabnext 2 | C tabclose 3 \ :C tabnext 2 | C tabclose 3
C tabnext 3 C tabnext 2
let g:r+=[tabpagenr().'/'.tabpagenr('$')] let g:r+=[tabpagenr().'/'.tabpagenr('$')]
endfunction endfunction
call Test() call Test()
@ -233,22 +229,14 @@ describe('tab pages', function()
WinEnter WinEnter
TabEnter TabEnter
BufEnter BufEnter
=== tabnext 3 === === tabnext 2 ===
BufLeave
WinLeave WinLeave
TabLeave TabLeave
WinEnter WinEnter
TabEnter TabEnter
=== tabnext 2 === === tabnext 2 ===
BufLeave
WinLeave
TabLeave
WinEnter
TabEnter
=== tabnext 2 ===
=== tabclose 3 ===
BufEnter
=== tabclose 3 === === tabclose 3 ===
2/2]]) 2/2]])
eq(2, eval("tabpagenr('$')"))
end) end)
end) end)