# HG changeset patch # User Bram Moolenaar # Date 1429632519 -7200 # Node ID c0bc9b60fb8aa73ec12e2c40852b0708bdc7fff8 # Parent 9b6995e939c5a93516aeb15705175b4f3225b5f1 patch 7.4.709 Problem: ":tabmove" does not work as documented. Solution: Make it work consistently. Update documentation and add tests. (Hirohito Higashi) diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt --- a/runtime/doc/tabpage.txt +++ b/runtime/doc/tabpage.txt @@ -202,23 +202,29 @@ REORDERING TAB PAGES: Move the current tab page to after tab page N. Use zero to make the current tab page the first one. Without N the tab page is made the last one. > + :.tabmove " do nothing :-tabmove " move the tab page to the left - :tabmove " move the tab page to the right - :.tabmove " as above - :+tabmove " as above + :+tabmove " move the tab page to the right :0tabmove " move the tab page to the beginning of the tab " list - :$tabmove " move the tab page to the end of the tab list -< + :tabmove 0 " as above + :tabmove " move the tab page to the last + :$tabmove " as above + :tabmove $ " as above :tabm[ove] +[N] :tabm[ove] -[N] Move the current tab page N places to the right (with +) or to - the left (with -). + the left (with -). > + :tabmove - " move the tab page to the left + :tabmove -1 " as above + :tabmove + " move the tab page to the right + :tabmove +1 " as above + Note that although it is possible to move a tab behind the N-th one by using -:Ntabmove, it is impossible to move it by N places by using :+Ntabmove. For -clarification what +N means in this context see |[range]|. +:Ntabmove. And move it by N places by using :+Ntabmove. For clarification what ++N means in this context see |[range]|. LOOPING OVER TAB PAGES: diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -8145,7 +8145,7 @@ ex_tabnext(eap) ex_tabmove(eap) exarg_T *eap; { - int tab_number = 9999; + int tab_number; if (eap->arg && *eap->arg != NUL) { @@ -8166,19 +8166,38 @@ ex_tabmove(eap) else p = eap->arg; - if (p == skipdigits(p)) - { - /* No numbers as argument. */ - eap->errmsg = e_invarg; - return; - } - - tab_number = getdigits(&p); - if (relative != 0) - tab_number = tab_number * relative + tabpage_index(curtab) - 1;; + 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); } diff --git a/src/testdir/test62.in b/src/testdir/test62.in --- a/src/testdir/test62.in +++ b/src/testdir/test62.in @@ -96,30 +96,44 @@ STARTTEST :" :for i in range(9) | tabnew | endfor 1gt -Go=tabpagenr()  +:$put =tabpagenr() :tabmove 5 -i=tabpagenr()  +:$put =tabpagenr() +:.tabmove +:$put =tabpagenr() +:tabmove - +:$put =tabpagenr() +:tabmove + +:$put =tabpagenr() :tabmove -2 -i=tabpagenr()  +:$put =tabpagenr() :tabmove +4 -i=tabpagenr()  +:$put =tabpagenr() :tabmove -i=tabpagenr()  +:$put =tabpagenr() :tabmove -20 -i=tabpagenr()  +:$put =tabpagenr() :tabmove +20 -i=tabpagenr()  +:$put =tabpagenr() +:0tabmove +:$put =tabpagenr() +:$tabmove +:$put =tabpagenr() +:tabmove 0 +:$put =tabpagenr() +:tabmove $ +:$put =tabpagenr() :3tabmove -i=tabpagenr()  +:$put =tabpagenr() :7tabmove 5 -i=tabpagenr()  +:$put =tabpagenr() :let a='No error caught.' :try :tabmove foo :catch E474 :let a='E474 caught.' :endtry -i=a  +:$put =a :" :" Test autocommands :tabonly! diff --git a/src/testdir/test62.ok b/src/testdir/test62.ok --- a/src/testdir/test62.ok +++ b/src/testdir/test62.ok @@ -9,14 +9,21 @@ tab drop 1: pass tab drop 2: pass tab drop 3: pass 1 -6 +5 +5 4 -8 +5 +3 +7 +10 +1 +10 +1 10 1 10 4 -6 +5 E474 caught. === tab split === WinLeave diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 709, +/**/ 708, /**/ 707, diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -4120,18 +4120,27 @@ goto_tabpage_win(tp, wp) } /* - * Move the current tab page to before tab page "nr". + * Move the current tab page to after tab page "nr". */ void tabpage_move(nr) int nr; { - int n = nr; - tabpage_T *tp; + int n = 1; + tabpage_T *tp, *tp_dst; if (first_tabpage->tp_next == NULL) return; + for (tp = first_tabpage; tp->tp_next != NULL && n < nr; tp = tp->tp_next) + ++n; + + if (tp == curtab || (nr > 0 && tp->tp_next != NULL + && tp->tp_next == curtab)) + return; + + tp_dst = tp; + /* Remove the current tab page from the list of tab pages. */ if (curtab == first_tabpage) first_tabpage = curtab->tp_next; @@ -4146,17 +4155,15 @@ tabpage_move(nr) } /* Re-insert it at the specified position. */ - if (n <= 0) + if (nr <= 0) { curtab->tp_next = first_tabpage; first_tabpage = curtab; } else { - for (tp = first_tabpage; tp->tp_next != NULL && n > 1; tp = tp->tp_next) - --n; - curtab->tp_next = tp->tp_next; - tp->tp_next = curtab; + curtab->tp_next = tp_dst->tp_next; + tp_dst->tp_next = curtab; } /* Need to redraw the tabline. Tab page contents doesn't change. */