Problem: ":tabmove" does not work as documented.
Solution: Make it work consistently. Update documentation and add tests.
(Hirohito Higashi)
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:
ex_tabmove(eap)
exarg_T *eap;
{
- int tab_number = 9999;
+ int tab_number;
if (eap->arg && *eap->arg != NUL)
{
else
p = eap->arg;
- if (p == skipdigits(p))
+ if (relative == 0)
{
- /* No numbers as argument. */
- eap->errmsg = e_invarg;
- return;
+ 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;
}
-
- tab_number = getdigits(&p);
- if (relative != 0)
- tab_number = tab_number * relative + tabpage_index(curtab) - 1;;
}
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);
}
:"
:for i in range(9) | tabnew | endfor
1gt
-Go\12=tabpagenr()\r\r\e
+:$put =tabpagenr()
:tabmove 5
-i\12=tabpagenr()\r\r\e
+:$put =tabpagenr()
+:.tabmove
+:$put =tabpagenr()
+:tabmove -
+:$put =tabpagenr()
+:tabmove +
+:$put =tabpagenr()
:tabmove -2
-i\12=tabpagenr()\r\r\e
+:$put =tabpagenr()
:tabmove +4
-i\12=tabpagenr()\r\r\e
+:$put =tabpagenr()
:tabmove
-i\12=tabpagenr()\r\r\e
+:$put =tabpagenr()
:tabmove -20
-i\12=tabpagenr()\r\r\e
+:$put =tabpagenr()
:tabmove +20
-i\12=tabpagenr()\r\r\e
+:$put =tabpagenr()
+:0tabmove
+:$put =tabpagenr()
+:$tabmove
+:$put =tabpagenr()
+:tabmove 0
+:$put =tabpagenr()
+:tabmove $
+:$put =tabpagenr()
:3tabmove
-i\12=tabpagenr()\r\r\e
+:$put =tabpagenr()
:7tabmove 5
-i\12=tabpagenr()\r\r\e
+:$put =tabpagenr()
:let a='No error caught.'
:try
:tabmove foo
:catch E474
:let a='E474 caught.'
:endtry
-i\12=a\r\e
+:$put =a
:"
:" Test autocommands
:tabonly!
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
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 709,
/**/
708,
/**/
}
/*
- * 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;
}
/* 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. */