Last active
January 29, 2017 03:31
-
-
Save h-east/4d42bf152311600c6a11ac06a292d14d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt | |
index bc40981..e72388c 100644 | |
--- a/runtime/doc/tabpage.txt | |
+++ b/runtime/doc/tabpage.txt | |
@@ -139,6 +139,10 @@ something else. | |
:+tabclose " close the next tab page | |
:1tabclose " close the first tab page | |
:$tabclose " close the last tab page | |
+ :tabclose -2 " close the two previous tab page | |
+ :tabclose + " close the next tab page | |
+ :tabclose 3 " close the third tab page | |
+ :tabclose $ " close the last tab page | |
< | |
*:tabo* *:tabonly* | |
:tabo[nly][!] Close all other tab pages. | |
@@ -153,13 +157,20 @@ something else. | |
" one | |
:{count}tabo[nly][!] | |
- Close all tab pages except the {count}th one. > | |
+:tabo[nly][!] {count} | |
+ Close all tab pages except {count} one. > | |
:.tabonly " as above | |
:-tabonly " close all tab pages except the previous | |
" one | |
:+tabonly " close all tab pages except the next one | |
:1tabonly " close all tab pages except the first one | |
:$tabonly " close all tab pages except the last one | |
+ :tabonly - " close all tab pages except the previous | |
+ " one | |
+ :tabonly +2 " close all tab pages except the two next | |
+ " one | |
+ :tabonly 1 " close all tab pages except the first one | |
+ :tabonly $ " close all tab pages except the last one | |
SWITCHING TO ANOTHER TAB PAGE: | |
@@ -174,7 +185,20 @@ gt *i_CTRL-<PageDown>* *i_<C-PageDown>* | |
Go to the next tab page. Wraps around from the last to the | |
first one. | |
+:{count}tabn[ext] | |
:tabn[ext] {count} | |
+ Go to tab page {count}. The first tab page has number one. > | |
+ :-tabnext " go to the previous tab page | |
+ :+tabnext " go to the next tab page | |
+ :+2tabnext " go to the two next tab page | |
+ :1tabnext " go to the first tab page | |
+ :$tabnext " go to the last tab page | |
+ :tabnext $ " as above | |
+ :tabnext - " go to the previous tab page | |
+ :tabnext -1 " as above | |
+ :tabnext + " go to the next tab page | |
+ :tabnext +1 " as above | |
+ | |
{count}<C-PageDown> | |
{count}gt Go to tab page {count}. The first tab page has number one. | |
diff --git a/src/ex_cmds.h b/src/ex_cmds.h | |
index d70ff6a..88dfbb9 100644 | |
--- a/src/ex_cmds.h | |
+++ b/src/ex_cmds.h | |
@@ -65,7 +65,8 @@ | |
#define ADDR_LOADED_BUFFERS 3 | |
#define ADDR_BUFFERS 4 | |
#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 | |
#ifndef DO_DECLARE_EXCMD | |
@@ -1425,9 +1426,9 @@ EX(CMD_tags, "tags", do_tags, | |
ADDR_LINES), | |
EX(CMD_tab, "tab", ex_wrongmodifier, | |
NEEDARG|EXTRA|NOTRLCOM, | |
- ADDR_LINES), | |
+ ADDR_TABS), | |
EX(CMD_tabclose, "tabclose", ex_tabclose, | |
- RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN, | |
+ BANG|RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN, | |
ADDR_TABS), | |
EX(CMD_tabdo, "tabdo", ex_listdo, | |
NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL, | |
@@ -1440,34 +1441,34 @@ EX(CMD_tabfind, "tabfind", ex_splitview, | |
ADDR_TABS), | |
EX(CMD_tabfirst, "tabfirst", ex_tabnext, | |
TRLBAR, | |
- ADDR_LINES), | |
+ ADDR_TABS), | |
EX(CMD_tabmove, "tabmove", ex_tabmove, | |
RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR, | |
ADDR_TABS), | |
EX(CMD_tablast, "tablast", ex_tabnext, | |
TRLBAR, | |
- ADDR_LINES), | |
+ ADDR_TABS), | |
EX(CMD_tabnext, "tabnext", ex_tabnext, | |
- RANGE|NOTADR|COUNT|TRLBAR, | |
- ADDR_LINES), | |
+ RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR, | |
+ ADDR_TABS), | |
EX(CMD_tabnew, "tabnew", ex_splitview, | |
BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR, | |
ADDR_TABS), | |
EX(CMD_tabonly, "tabonly", ex_tabonly, | |
- BANG|RANGE|NOTADR|TRLBAR|CMDWIN, | |
+ BANG|RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN, | |
ADDR_TABS), | |
EX(CMD_tabprevious, "tabprevious", ex_tabnext, | |
- RANGE|NOTADR|COUNT|TRLBAR, | |
- ADDR_LINES), | |
+ RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR, | |
+ ADDR_TABS_RELATIVE), | |
EX(CMD_tabNext, "tabNext", ex_tabnext, | |
- RANGE|NOTADR|COUNT|TRLBAR, | |
- ADDR_LINES), | |
+ RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR, | |
+ ADDR_TABS_RELATIVE), | |
EX(CMD_tabrewind, "tabrewind", ex_tabnext, | |
TRLBAR, | |
- ADDR_LINES), | |
+ ADDR_TABS), | |
EX(CMD_tabs, "tabs", ex_tabs, | |
TRLBAR|CMDWIN, | |
- ADDR_LINES), | |
+ ADDR_TABS), | |
EX(CMD_tcl, "tcl", ex_tcl, | |
RANGE|EXTRA|NEEDARG|CMDWIN, | |
ADDR_LINES), | |
diff --git a/src/ex_docmd.c b/src/ex_docmd.c | |
index 192f45d..f8c9497 100644 | |
--- a/src/ex_docmd.c | |
+++ b/src/ex_docmd.c | |
@@ -2162,8 +2162,7 @@ do_one_cmd( | |
ea.line2 = curwin->w_cursor.lnum; | |
break; | |
case ADDR_WINDOWS: | |
- lnum = CURRENT_WIN_NR; | |
- ea.line2 = lnum; | |
+ ea.line2 = CURRENT_WIN_NR; | |
break; | |
case ADDR_ARGUMENTS: | |
ea.line2 = curwin->w_arg_idx + 1; | |
@@ -2175,8 +2174,10 @@ do_one_cmd( | |
ea.line2 = curbuf->b_fnum; | |
break; | |
case ADDR_TABS: | |
- lnum = CURRENT_TAB_NR; | |
- ea.line2 = lnum; | |
+ ea.line2 = CURRENT_TAB_NR; | |
+ break; | |
+ case ADDR_TABS_RELATIVE: | |
+ ea.line2 = 1; | |
break; | |
#ifdef FEAT_QUICKFIX | |
case ADDR_QUICKFIX: | |
@@ -2235,6 +2236,10 @@ do_one_cmd( | |
goto doend; | |
} | |
break; | |
+ case ADDR_TABS_RELATIVE: | |
+ errormsg = (char_u *)_(e_invrange); | |
+ goto doend; | |
+ break; | |
case ADDR_ARGUMENTS: | |
if (ARGCOUNT == 0) | |
ea.line1 = ea.line2 = 0; | |
@@ -2710,6 +2715,9 @@ do_one_cmd( | |
case ADDR_TABS: | |
ea.line2 = LAST_TAB_NR; | |
break; | |
+ case ADDR_TABS_RELATIVE: | |
+ ea.line2 = 1; | |
+ break; | |
case ADDR_ARGUMENTS: | |
if (ARGCOUNT == 0) | |
ea.line1 = ea.line2 = 0; | |
@@ -2786,7 +2794,8 @@ do_one_cmd( | |
/* | |
* 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; | |
} | |
} | |
@@ -4427,6 +4436,11 @@ get_address( | |
case ADDR_TABS: | |
lnum = CURRENT_TAB_NR; | |
break; | |
+ case ADDR_TABS_RELATIVE: | |
+ EMSG(_(e_invrange)); | |
+ cmd = NULL; | |
+ goto error; | |
+ break; | |
#ifdef FEAT_QUICKFIX | |
case ADDR_QUICKFIX: | |
lnum = qf_get_cur_valid_idx(eap); | |
@@ -4464,6 +4478,11 @@ get_address( | |
case ADDR_TABS: | |
lnum = LAST_TAB_NR; | |
break; | |
+ case ADDR_TABS_RELATIVE: | |
+ EMSG(_(e_invrange)); | |
+ cmd = NULL; | |
+ goto error; | |
+ break; | |
#ifdef FEAT_QUICKFIX | |
case ADDR_QUICKFIX: | |
lnum = qf_get_size(eap); | |
@@ -4646,6 +4665,9 @@ get_address( | |
case ADDR_TABS: | |
lnum = CURRENT_TAB_NR; | |
break; | |
+ case ADDR_TABS_RELATIVE: | |
+ lnum = 1; | |
+ break; | |
#ifdef FEAT_QUICKFIX | |
case ADDR_QUICKFIX: | |
lnum = qf_get_cur_valid_idx(eap); | |
@@ -4662,7 +4684,14 @@ get_address( | |
n = 1; | |
else | |
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) | |
lnum = compute_buffer_local_count( | |
addr_type, lnum, (i == '-') ? -1 * n : n); | |
@@ -4795,6 +4824,9 @@ invalid_range(exarg_T *eap) | |
if (eap->line2 > LAST_TAB_NR) | |
return (char_u *)_(e_invrange); | |
break; | |
+ case ADDR_TABS_RELATIVE: | |
+ /* Do nothing */ | |
+ break; | |
#ifdef FEAT_QUICKFIX | |
case ADDR_QUICKFIX: | |
if (eap->line2 != 1 && eap->line2 > qf_get_size(eap)) | |
@@ -5453,6 +5485,105 @@ getargopt(exarg_T *eap) | |
} | |
/* | |
+ * Get argument for tabpage related ex command | |
+ * Returns a tabpage number. | |
+ * When error, eap->errmsg set to not a NULL. | |
+ */ | |
+ 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. | |
*/ | |
static void | |
@@ -7444,6 +7575,7 @@ ex_win_close( | |
ex_tabclose(exarg_T *eap) | |
{ | |
tabpage_T *tp; | |
+ int tab_number; | |
# ifdef FEAT_CMDWIN | |
if (cmdwin_type != 0) | |
@@ -7454,9 +7586,10 @@ ex_tabclose(exarg_T *eap) | |
EMSG(_("E784: Cannot close last tab page")); | |
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) | |
{ | |
beep_flush(); | |
@@ -7467,13 +7600,13 @@ ex_tabclose(exarg_T *eap) | |
tabpage_close_other(tp, eap->forceit); | |
return; | |
} | |
- } | |
- if (!text_locked() | |
+ else if (!text_locked() | |
#ifdef FEAT_AUTOCMD | |
- && !curbuf_locked() | |
+ && !curbuf_locked() | |
#endif | |
- ) | |
- tabpage_close(eap->forceit); | |
+ ) | |
+ tabpage_close(eap->forceit); | |
+ } | |
} | |
} | |
@@ -7485,6 +7618,7 @@ ex_tabonly(exarg_T *eap) | |
{ | |
tabpage_T *tp; | |
int done; | |
+ int tab_number; | |
# ifdef FEAT_CMDWIN | |
if (cmdwin_type != 0) | |
@@ -7495,24 +7629,27 @@ ex_tabonly(exarg_T *eap) | |
MSG(_("Already only one tab page")); | |
else | |
{ | |
- if (eap->addr_count > 0) | |
- goto_tabpage(eap->line2); | |
- /* Repeat this up to a 1000 times, because autocommands may mess | |
- * up the lists. */ | |
- for (done = 0; done < 1000; ++done) | |
+ tab_number = get_tabpage_arg(eap); | |
+ if (eap->errmsg == NULL) | |
{ | |
- FOR_ALL_TABPAGES(tp) | |
- if (tp->tp_topframe != topframe) | |
- { | |
- 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 */ | |
+ goto_tabpage(tab_number); | |
+ /* Repeat this up to a 1000 times, because autocommands may | |
+ * mess up the lists. */ | |
+ for (done = 0; done < 1000; ++done) | |
+ { | |
+ FOR_ALL_TABPAGES(tp) | |
+ if (tp->tp_topframe != topframe) | |
+ { | |
+ 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; | |
- } | |
- if (first_tabpage->tp_next == NULL) | |
- break; | |
+ } | |
} | |
} | |
} | |
@@ -8254,6 +8391,8 @@ tabpage_new(void) | |
static void | |
ex_tabnext(exarg_T *eap) | |
{ | |
+ int tab_number; | |
+ | |
switch (eap->cmdidx) | |
{ | |
case CMD_tabfirst: | |
@@ -8265,10 +8404,40 @@ ex_tabnext(exarg_T *eap) | |
break; | |
case CMD_tabprevious: | |
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; | |
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; | |
} | |
} | |
@@ -8281,59 +8450,9 @@ ex_tabmove(exarg_T *eap) | |
{ | |
int tab_number; | |
- if (eap->arg && *eap->arg != NUL) | |
- { | |
- 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); | |
+ tab_number = get_tabpage_arg(eap); | |
+ if (eap->errmsg == NULL) | |
+ tabpage_move(tab_number); | |
} | |
/* | |
diff --git a/src/testdir/test_tabpage.vim b/src/testdir/test_tabpage.vim | |
index 1720107..64103c5 100644 | |
--- a/src/testdir/test_tabpage.vim | |
+++ b/src/testdir/test_tabpage.vim | |
@@ -94,10 +94,6 @@ function Test_tabpage() | |
call assert_equal(7, tabpagenr()) | |
tabmove | |
call assert_equal(10, tabpagenr()) | |
- tabmove -20 | |
- call assert_equal(1, tabpagenr()) | |
- tabmove +20 | |
- call assert_equal(10, tabpagenr()) | |
0tabmove | |
call assert_equal(1, tabpagenr()) | |
$tabmove | |
@@ -110,7 +106,16 @@ function Test_tabpage() | |
call assert_equal(4, tabpagenr()) | |
7tabmove 5 | |
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 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 | |
" Test autocommands | |
@@ -118,7 +123,6 @@ function Test_tabpage_with_autocmd() | |
if !has('autocmd') | |
return | |
endif | |
- tabonly! | |
command -nargs=1 -bar C :call add(s:li, '=== ' . <q-args> . ' ===')|<args> | |
augroup TestTabpageGroup | |
au! | |
@@ -181,19 +185,20 @@ function Test_tabpage_with_autocmd() | |
C tabnext 1 | |
call assert_equal(['=== tabnext 1 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufEnter'], s:li) | |
- autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3 | |
- let s:li = [] | |
- C tabnext 3 | |
- 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) | |
- call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')]) | |
+" autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3 | |
+" let s:li = [] | |
+" call assert_equal(89, tabpagenr('$')) | |
+" C tabnext 3 | |
+" call assert_equal(88, 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) | |
+" call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')]) | |
delcommand C | |
autocmd! TabDestructive | |
augroup! TabDestructive | |
autocmd! TestTabpageGroup | |
augroup! TestTabpageGroup | |
- tabonly! | |
- bw! | |
+ 1tabonly! | |
endfunction | |
function Test_tabpage_with_tab_modifier() | |
@@ -224,8 +229,223 @@ function Test_tabpage_with_tab_modifier() | |
call assert_fails('-99tab help', 'E16:') | |
delfunction s:check_tab | |
- tabonly! | |
- bw! | |
+ 1tabonly! | |
+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() | |
+ | |
+ " Check the normal behavior (pre count only) | |
+ let tc = [ [4, '.', '!'], [3, '.+', '!'], [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 | |
+ | |
+ " Check 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 | |
+ | |
+ " Check 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 | |
+ | |
+ " Check 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 | |
func Test_tabnext_on_buf_unload1() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment