0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.0.0259: tab commands do not handle count correctly

Problem:    Tab commands do not handle count correctly. (Ken Hamada)
Solution:   Add ADDR_TABS_RELATIVE. (Hirohito Higashi)
This commit is contained in:
Bram Moolenaar
2017-01-29 14:48:10 +01:00
parent c9b56b2ceb
commit 2f72c70657
4 changed files with 450 additions and 109 deletions

View File

@@ -65,7 +65,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
#ifndef DO_DECLARE_EXCMD #ifndef DO_DECLARE_EXCMD
@@ -1425,9 +1426,9 @@ EX(CMD_tags, "tags", do_tags,
ADDR_LINES), ADDR_LINES),
EX(CMD_tab, "tab", ex_wrongmodifier, EX(CMD_tab, "tab", ex_wrongmodifier,
NEEDARG|EXTRA|NOTRLCOM, NEEDARG|EXTRA|NOTRLCOM,
ADDR_LINES), ADDR_TABS),
EX(CMD_tabclose, "tabclose", ex_tabclose, EX(CMD_tabclose, "tabclose", ex_tabclose,
RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN, BANG|RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN,
ADDR_TABS), ADDR_TABS),
EX(CMD_tabdo, "tabdo", ex_listdo, EX(CMD_tabdo, "tabdo", ex_listdo,
NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL, NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL,
@@ -1440,34 +1441,34 @@ EX(CMD_tabfind, "tabfind", ex_splitview,
ADDR_TABS), ADDR_TABS),
EX(CMD_tabfirst, "tabfirst", ex_tabnext, EX(CMD_tabfirst, "tabfirst", ex_tabnext,
TRLBAR, TRLBAR,
ADDR_LINES), ADDR_TABS),
EX(CMD_tabmove, "tabmove", ex_tabmove, EX(CMD_tabmove, "tabmove", ex_tabmove,
RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR, RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR,
ADDR_TABS), ADDR_TABS),
EX(CMD_tablast, "tablast", ex_tabnext, EX(CMD_tablast, "tablast", ex_tabnext,
TRLBAR, TRLBAR,
ADDR_LINES), ADDR_TABS),
EX(CMD_tabnext, "tabnext", ex_tabnext, EX(CMD_tabnext, "tabnext", ex_tabnext,
RANGE|NOTADR|COUNT|TRLBAR, RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR,
ADDR_LINES), ADDR_TABS),
EX(CMD_tabnew, "tabnew", ex_splitview, EX(CMD_tabnew, "tabnew", ex_splitview,
BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR, BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR,
ADDR_TABS), ADDR_TABS),
EX(CMD_tabonly, "tabonly", ex_tabonly, EX(CMD_tabonly, "tabonly", ex_tabonly,
BANG|RANGE|NOTADR|TRLBAR|CMDWIN, BANG|RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN,
ADDR_TABS), ADDR_TABS),
EX(CMD_tabprevious, "tabprevious", ex_tabnext, EX(CMD_tabprevious, "tabprevious", ex_tabnext,
RANGE|NOTADR|COUNT|TRLBAR, RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR,
ADDR_LINES), ADDR_TABS_RELATIVE),
EX(CMD_tabNext, "tabNext", ex_tabnext, EX(CMD_tabNext, "tabNext", ex_tabnext,
RANGE|NOTADR|COUNT|TRLBAR, RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR,
ADDR_LINES), ADDR_TABS_RELATIVE),
EX(CMD_tabrewind, "tabrewind", ex_tabnext, EX(CMD_tabrewind, "tabrewind", ex_tabnext,
TRLBAR, TRLBAR,
ADDR_LINES), ADDR_TABS),
EX(CMD_tabs, "tabs", ex_tabs, EX(CMD_tabs, "tabs", ex_tabs,
TRLBAR|CMDWIN, TRLBAR|CMDWIN,
ADDR_LINES), ADDR_TABS),
EX(CMD_tcl, "tcl", ex_tcl, EX(CMD_tcl, "tcl", ex_tcl,
RANGE|EXTRA|NEEDARG|CMDWIN, RANGE|EXTRA|NEEDARG|CMDWIN,
ADDR_LINES), ADDR_LINES),

View File

@@ -2162,8 +2162,7 @@ do_one_cmd(
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;
@@ -2175,8 +2174,10 @@ do_one_cmd(
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;
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
@@ -2235,6 +2236,10 @@ do_one_cmd(
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;
@@ -2710,6 +2715,9 @@ do_one_cmd(
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;
@@ -2786,7 +2794,8 @@ do_one_cmd(
/* /*
* Be vi compatible: no error message for out of range. * Be vi compatible: no error message for out of range.
*/ */
if (ea.line2 > curbuf->b_ml.ml_line_count) if (ea.addr_type == ADDR_LINES
&& ea.line2 > curbuf->b_ml.ml_line_count)
ea.line2 = curbuf->b_ml.ml_line_count; ea.line2 = curbuf->b_ml.ml_line_count;
} }
} }
@@ -4427,6 +4436,11 @@ get_address(
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;
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
lnum = qf_get_cur_valid_idx(eap); lnum = qf_get_cur_valid_idx(eap);
@@ -4464,6 +4478,11 @@ get_address(
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;
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
lnum = qf_get_size(eap); lnum = qf_get_size(eap);
@@ -4646,6 +4665,9 @@ get_address(
case ADDR_TABS: case ADDR_TABS:
lnum = CURRENT_TAB_NR; lnum = CURRENT_TAB_NR;
break; break;
case ADDR_TABS_RELATIVE:
lnum = 1;
break;
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
lnum = qf_get_cur_valid_idx(eap); lnum = qf_get_cur_valid_idx(eap);
@@ -4662,7 +4684,14 @@ get_address(
n = 1; n = 1;
else else
n = getdigits(&cmd); n = getdigits(&cmd);
if (addr_type == ADDR_LOADED_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) || 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);
@@ -4795,6 +4824,9 @@ invalid_range(exarg_T *eap)
if (eap->line2 > LAST_TAB_NR) if (eap->line2 > LAST_TAB_NR)
return (char_u *)_(e_invrange); return (char_u *)_(e_invrange);
break; break;
case ADDR_TABS_RELATIVE:
/* Do nothing */
break;
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
if (eap->line2 != 1 && eap->line2 > qf_get_size(eap)) if (eap->line2 != 1 && eap->line2 > qf_get_size(eap))
@@ -5452,6 +5484,104 @@ 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.
*/ */
@@ -7444,6 +7574,7 @@ ex_win_close(
ex_tabclose(exarg_T *eap) ex_tabclose(exarg_T *eap)
{ {
tabpage_T *tp; tabpage_T *tp;
int tab_number;
# ifdef FEAT_CMDWIN # ifdef FEAT_CMDWIN
if (cmdwin_type != 0) if (cmdwin_type != 0)
@@ -7454,9 +7585,10 @@ ex_tabclose(exarg_T *eap)
EMSG(_("E784: Cannot close last tab page")); EMSG(_("E784: Cannot close last tab page"));
else else
{ {
if (eap->addr_count > 0) tab_number = get_tabpage_arg(eap);
if (eap->errmsg == NULL)
{ {
tp = find_tabpage((int)eap->line2); tp = find_tabpage(tab_number);
if (tp == NULL) if (tp == NULL)
{ {
beep_flush(); beep_flush();
@@ -7467,13 +7599,13 @@ ex_tabclose(exarg_T *eap)
tabpage_close_other(tp, eap->forceit); tabpage_close_other(tp, eap->forceit);
return; return;
} }
} else if (!text_locked()
if (!text_locked()
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
&& !curbuf_locked() && !curbuf_locked()
#endif #endif
) )
tabpage_close(eap->forceit); tabpage_close(eap->forceit);
}
} }
} }
@@ -7485,6 +7617,7 @@ ex_tabonly(exarg_T *eap)
{ {
tabpage_T *tp; tabpage_T *tp;
int done; int done;
int tab_number;
# ifdef FEAT_CMDWIN # ifdef FEAT_CMDWIN
if (cmdwin_type != 0) if (cmdwin_type != 0)
@@ -7495,24 +7628,27 @@ ex_tabonly(exarg_T *eap)
MSG(_("Already only one tab page")); MSG(_("Already only one tab page"));
else else
{ {
if (eap->addr_count > 0) 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
* up the lists. */
for (done = 0; done < 1000; ++done)
{ {
FOR_ALL_TABPAGES(tp) goto_tabpage(tab_number);
if (tp->tp_topframe != topframe) /* Repeat this up to a 1000 times, because autocommands may
{ * mess up the lists. */
tabpage_close_other(tp, eap->forceit); for (done = 0; done < 1000; ++done)
/* if we failed to close it quit */ {
if (valid_tabpage(tp)) FOR_ALL_TABPAGES(tp)
done = 1000; if (tp->tp_topframe != topframe)
/* start over, "tp" is now invalid */ {
tabpage_close_other(tp, eap->forceit);
/* if we failed to close it quit */
if (valid_tabpage(tp))
done = 1000;
/* start over, "tp" is now invalid */
break;
}
if (first_tabpage->tp_next == NULL)
break; break;
} }
if (first_tabpage->tp_next == NULL)
break;
} }
} }
} }
@@ -8254,6 +8390,8 @@ tabpage_new(void)
static void static void
ex_tabnext(exarg_T *eap) ex_tabnext(exarg_T *eap)
{ {
int tab_number;
switch (eap->cmdidx) switch (eap->cmdidx)
{ {
case CMD_tabfirst: case CMD_tabfirst:
@@ -8265,10 +8403,40 @@ 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;
} }
} }
@@ -8281,59 +8449,9 @@ ex_tabmove(exarg_T *eap)
{ {
int tab_number; int tab_number;
if (eap->arg && *eap->arg != NUL) tab_number = get_tabpage_arg(eap);
{ if (eap->errmsg == NULL)
char_u *p = eap->arg; tabpage_move(tab_number);
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

@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
259,
/**/ /**/
258, 258,
/**/ /**/