To: vim_dev@googlegroups.com Subject: Patch 8.0.0259 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0259 Problem: Tab commands do not handle count correctly. (Ken Hamada) Solution: Add ADDR_TABS_RELATIVE. (Hirohito Higashi) Files: runtime/doc/tabpage.txt, src/ex_cmds.h, src/ex_docmd.c, src/testdir/test_tabpage.vim *** ../vim-8.0.0258/runtime/doc/tabpage.txt 2016-09-12 12:45:48.000000000 +0200 --- runtime/doc/tabpage.txt 2017-01-29 14:26:29.892913581 +0100 *************** *** 58,63 **** --- 58,65 ---- In the GUI tab pages line you can use the right mouse button to open menu. |tabline-menu|. + For the related autocommands see |tabnew-autocmd|. + :[count]tabe[dit] *:tabe* *:tabedit* *:tabnew* :[count]tabnew Open a new tab page with an empty window, after the current *************** *** 137,142 **** --- 139,148 ---- :+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. *************** *** 151,163 **** " one :{count}tabo[nly][!] ! Close all tab pages except the {count}th 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 SWITCHING TO ANOTHER TAB PAGE: --- 157,176 ---- " one :{count}tabo[nly][!] ! :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: *************** *** 172,178 **** --- 185,204 ---- 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} {count}gt Go to tab page {count}. The first tab page has number one. *************** *** 287,292 **** --- 313,319 ---- Currently there is only one option local to a tab page: 'cmdheight'. + *tabnew-autocmd* The TabLeave and TabEnter autocommand events can be used to do something when switching from one tab page to another. The exact order depends on what you are doing. When creating a new tab page this works as if you create a new *** ../vim-8.0.0258/src/ex_cmds.h 2017-01-28 15:58:45.344197275 +0100 --- src/ex_cmds.h 2017-01-29 14:26:29.892913581 +0100 *************** *** 65,71 **** #define ADDR_LOADED_BUFFERS 3 #define ADDR_BUFFERS 4 #define ADDR_TABS 5 ! #define ADDR_QUICKFIX 6 #define ADDR_OTHER 99 #ifndef DO_DECLARE_EXCMD --- 65,72 ---- #define ADDR_LOADED_BUFFERS 3 #define ADDR_BUFFERS 4 #define ADDR_TABS 5 ! #define ADDR_TABS_RELATIVE 6 /* Tab page that only relative */ ! #define ADDR_QUICKFIX 7 #define ADDR_OTHER 99 #ifndef DO_DECLARE_EXCMD *************** *** 1425,1433 **** ADDR_LINES), EX(CMD_tab, "tab", ex_wrongmodifier, NEEDARG|EXTRA|NOTRLCOM, ! ADDR_LINES), EX(CMD_tabclose, "tabclose", ex_tabclose, ! RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN, ADDR_TABS), EX(CMD_tabdo, "tabdo", ex_listdo, NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL, --- 1426,1434 ---- ADDR_LINES), EX(CMD_tab, "tab", ex_wrongmodifier, NEEDARG|EXTRA|NOTRLCOM, ! ADDR_TABS), EX(CMD_tabclose, "tabclose", ex_tabclose, ! BANG|RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN, ADDR_TABS), EX(CMD_tabdo, "tabdo", ex_listdo, NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL, *************** *** 1440,1473 **** ADDR_TABS), EX(CMD_tabfirst, "tabfirst", ex_tabnext, TRLBAR, ! ADDR_LINES), EX(CMD_tabmove, "tabmove", ex_tabmove, RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR, ADDR_TABS), EX(CMD_tablast, "tablast", ex_tabnext, TRLBAR, ! ADDR_LINES), EX(CMD_tabnext, "tabnext", ex_tabnext, ! RANGE|NOTADR|COUNT|TRLBAR, ! ADDR_LINES), 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, ADDR_TABS), EX(CMD_tabprevious, "tabprevious", ex_tabnext, ! RANGE|NOTADR|COUNT|TRLBAR, ! ADDR_LINES), EX(CMD_tabNext, "tabNext", ex_tabnext, ! RANGE|NOTADR|COUNT|TRLBAR, ! ADDR_LINES), EX(CMD_tabrewind, "tabrewind", ex_tabnext, TRLBAR, ! ADDR_LINES), EX(CMD_tabs, "tabs", ex_tabs, TRLBAR|CMDWIN, ! ADDR_LINES), EX(CMD_tcl, "tcl", ex_tcl, RANGE|EXTRA|NEEDARG|CMDWIN, ADDR_LINES), --- 1441,1474 ---- ADDR_TABS), EX(CMD_tabfirst, "tabfirst", ex_tabnext, TRLBAR, ! ADDR_TABS), EX(CMD_tabmove, "tabmove", ex_tabmove, RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR, ADDR_TABS), EX(CMD_tablast, "tablast", ex_tabnext, TRLBAR, ! ADDR_TABS), EX(CMD_tabnext, "tabnext", ex_tabnext, ! 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|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN, ADDR_TABS), EX(CMD_tabprevious, "tabprevious", ex_tabnext, ! RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR, ! ADDR_TABS_RELATIVE), EX(CMD_tabNext, "tabNext", ex_tabnext, ! RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR, ! ADDR_TABS_RELATIVE), EX(CMD_tabrewind, "tabrewind", ex_tabnext, TRLBAR, ! ADDR_TABS), EX(CMD_tabs, "tabs", ex_tabs, TRLBAR|CMDWIN, ! ADDR_TABS), EX(CMD_tcl, "tcl", ex_tcl, RANGE|EXTRA|NEEDARG|CMDWIN, ADDR_LINES), *** ../vim-8.0.0258/src/ex_docmd.c 2017-01-28 17:11:09.724620245 +0100 --- src/ex_docmd.c 2017-01-29 14:44:57.129686401 +0100 *************** *** 2162,2169 **** ea.line2 = curwin->w_cursor.lnum; break; case ADDR_WINDOWS: ! lnum = CURRENT_WIN_NR; ! ea.line2 = lnum; break; case ADDR_ARGUMENTS: ea.line2 = curwin->w_arg_idx + 1; --- 2162,2168 ---- ea.line2 = curwin->w_cursor.lnum; break; case ADDR_WINDOWS: ! ea.line2 = CURRENT_WIN_NR; break; case ADDR_ARGUMENTS: ea.line2 = curwin->w_arg_idx + 1; *************** *** 2175,2182 **** ea.line2 = curbuf->b_fnum; break; case ADDR_TABS: ! lnum = CURRENT_TAB_NR; ! ea.line2 = lnum; break; #ifdef FEAT_QUICKFIX case ADDR_QUICKFIX: --- 2174,2183 ---- ea.line2 = curbuf->b_fnum; break; case ADDR_TABS: ! ea.line2 = CURRENT_TAB_NR; ! break; ! case ADDR_TABS_RELATIVE: ! ea.line2 = 1; break; #ifdef FEAT_QUICKFIX case ADDR_QUICKFIX: *************** *** 2235,2240 **** --- 2236,2245 ---- 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,2715 **** --- 2715,2723 ---- 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,2792 **** /* * Be vi compatible: no error message for out of range. */ ! if (ea.line2 > curbuf->b_ml.ml_line_count) ea.line2 = curbuf->b_ml.ml_line_count; } } --- 2794,2801 ---- /* * Be vi compatible: no error message for out of range. */ ! if (ea.addr_type == ADDR_LINES ! && ea.line2 > curbuf->b_ml.ml_line_count) ea.line2 = curbuf->b_ml.ml_line_count; } } *************** *** 4427,4432 **** --- 4436,4446 ---- 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,4469 **** --- 4478,4488 ---- 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,4651 **** --- 4665,4673 ---- 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,4668 **** n = 1; else n = getdigits(&cmd); ! if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS) lnum = compute_buffer_local_count( addr_type, lnum, (i == '-') ? -1 * n : n); --- 4684,4697 ---- n = 1; else n = getdigits(&cmd); ! ! 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,4800 **** --- 4824,4832 ---- 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,5458 **** --- 5485,5588 ---- } /* + * 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. */ static void *************** *** 7444,7449 **** --- 7574,7580 ---- ex_tabclose(exarg_T *eap) { tabpage_T *tp; + int tab_number; # ifdef FEAT_CMDWIN if (cmdwin_type != 0) *************** *** 7454,7462 **** EMSG(_("E784: Cannot close last tab page")); else { ! if (eap->addr_count > 0) { ! tp = find_tabpage((int)eap->line2); if (tp == NULL) { beep_flush(); --- 7585,7594 ---- EMSG(_("E784: Cannot close last tab page")); else { ! tab_number = get_tabpage_arg(eap); ! if (eap->errmsg == NULL) { ! tp = find_tabpage(tab_number); if (tp == NULL) { beep_flush(); *************** *** 7467,7479 **** tabpage_close_other(tp, eap->forceit); return; } ! } ! if (!text_locked() #ifdef FEAT_AUTOCMD ! && !curbuf_locked() #endif ! ) ! tabpage_close(eap->forceit); } } --- 7599,7611 ---- tabpage_close_other(tp, eap->forceit); return; } ! else if (!text_locked() #ifdef FEAT_AUTOCMD ! && !curbuf_locked() #endif ! ) ! tabpage_close(eap->forceit); ! } } } *************** *** 7485,7490 **** --- 7617,7623 ---- { tabpage_T *tp; int done; + int tab_number; # ifdef FEAT_CMDWIN if (cmdwin_type != 0) *************** *** 7495,7518 **** 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) { ! 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; } } } --- 7628,7654 ---- MSG(_("Already only one tab page")); else { ! tab_number = get_tabpage_arg(eap); ! if (eap->errmsg == NULL) { ! 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; ! } } } } *************** *** 8254,8259 **** --- 8390,8397 ---- static void ex_tabnext(exarg_T *eap) { + int tab_number; + switch (eap->cmdidx) { case CMD_tabfirst: *************** *** 8265,8274 **** break; case CMD_tabprevious: case CMD_tabNext: ! goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2); break; default: /* CMD_tabnext */ ! goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2); break; } } --- 8403,8442 ---- break; case CMD_tabprevious: case CMD_tabNext: ! 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 */ ! tab_number = get_tabpage_arg(eap); ! if (eap->errmsg == NULL) ! goto_tabpage(tab_number); break; } } *************** *** 8281,8339 **** { 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); } /* --- 8449,8457 ---- { int tab_number; ! tab_number = get_tabpage_arg(eap); ! if (eap->errmsg == NULL) ! tabpage_move(tab_number); } /* *** ../vim-8.0.0258/src/testdir/test_tabpage.vim 2016-12-01 17:48:24.910803059 +0100 --- src/testdir/test_tabpage.vim 2017-01-29 14:26:29.900913529 +0100 *************** *** 94,103 **** 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 --- 94,99 ---- *************** *** 110,116 **** --- 106,121 ---- 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,124 **** if !has('autocmd') return endif - tabonly! command -nargs=1 -bar C :call add(s:li, '=== ' . . ' ===')| augroup TestTabpageGroup au! --- 123,128 ---- *************** *** 183,190 **** 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('$')]) delcommand C --- 187,196 ---- autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3 let s:li = [] ! call assert_equal(3, tabpagenr('$')) ! 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('$')]) delcommand C *************** *** 192,199 **** augroup! TabDestructive autocmd! TestTabpageGroup augroup! TestTabpageGroup ! tabonly! ! bw! endfunction function Test_tabpage_with_tab_modifier() --- 198,204 ---- augroup! TabDestructive autocmd! TestTabpageGroup augroup! TestTabpageGroup ! 1tabonly! endfunction function Test_tabpage_with_tab_modifier() *************** *** 224,231 **** call assert_fails('-99tab help', 'E16:') delfunction s:check_tab ! tabonly! ! bw! endfunction func Test_tabnext_on_buf_unload1() --- 229,451 ---- call assert_fails('-99tab help', 'E16:') delfunction s:check_tab ! 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() ! ! " 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 func Test_tabnext_on_buf_unload1() *** ../vim-8.0.0258/src/version.c 2017-01-29 14:14:04.549800163 +0100 --- src/version.c 2017-01-29 14:27:04.456687434 +0100 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 259, /**/ -- CRONE: Who sent you? ARTHUR: The Knights Who Say Ni! CRONE: Aaaagh! (she looks around in rear) No! We have no shrubberies here. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///