summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2015-04-21 18:08:39 +0200
committerBram Moolenaar <Bram@vim.org>2015-04-21 18:08:39 +0200
commit40ce3a4e1f50badb75ca812e26557a9bc5fde8c6 (patch)
tree76b61256322ed7d01bbd3913ec3ae45f9d826b5a
parent77354e78a887e1b59ac519c5a1cb0e7fe9fc5899 (diff)
downloadvim-40ce3a4e1f50badb75ca812e26557a9bc5fde8c6.zip
patch 7.4.709
Problem: ":tabmove" does not work as documented. Solution: Make it work consistently. Update documentation and add tests. (Hirohito Higashi)
-rw-r--r--runtime/doc/tabpage.txt22
-rw-r--r--src/ex_docmd.c37
-rw-r--r--src/testdir/test62.in34
-rw-r--r--src/testdir/test62.ok13
-rw-r--r--src/version.c2
-rw-r--r--src/window.c23
6 files changed, 93 insertions, 38 deletions
diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt
index 2d44fe2ff..46e0a8fde 100644
--- 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
index e46ea05c1..af63b6c41 100644
--- 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))
+ 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);
}
diff --git a/src/testdir/test62.in b/src/testdir/test62.in
index c201fe713..c437f36a8 100644
--- 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
index e35b2b1c6..a0115bf6c 100644
--- 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
index a80370871..850f37c4c 100644
--- 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
index 952143003..609ab3e6a 100644
--- 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. */