aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/tabpage.txt23
-rw-r--r--src/nvim/ex_docmd.c38
-rw-r--r--src/nvim/version.c2
-rw-r--r--src/nvim/window.c30
-rw-r--r--test/functional/legacy/062_tab_pages_spec.lua22
5 files changed, 81 insertions, 34 deletions
diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt
index 13944dc02a..59c4a28ff2 100644
--- a/runtime/doc/tabpage.txt
+++ b/runtime/doc/tabpage.txt
@@ -197,22 +197,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/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index cbe7c1a231..1ae440c757 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -6345,7 +6345,7 @@ static void ex_tabnext(exarg_T *eap)
*/
static void ex_tabmove(exarg_T *eap)
{
- int tab_number = 9999;
+ int tab_number;
if (eap->arg && *eap->arg != NUL) {
char_u *p = eap->arg;
@@ -6361,17 +6361,35 @@ static void ex_tabmove(exarg_T *eap)
} else
p = eap->arg;
- if (p == skipdigits(p)) {
- /* No numbers as argument. */
- eap->errmsg = e_invarg;
- return;
+ 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;
+ }
}
-
- tab_number = getdigits_int(&p);
- if (relative != 0)
- tab_number = tab_number * relative + tabpage_index(curtab) - 1; ;
- } else if (eap->addr_count != 0)
+ } 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/nvim/version.c b/src/nvim/version.c
index c3555a9731..99484dd21d 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -453,7 +453,7 @@ static int included_patches[] = {
712,
711,
710,
- // 709,
+ 709,
// 708,
707,
706,
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 191cb04d75..e84d8df36b 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3281,17 +3281,27 @@ void goto_tabpage_win(tabpage_T *tp, win_T *wp)
}
}
-/*
- * Move the current tab page to before tab page "nr".
- */
+// Move the current tab page to after tab page "nr".
void tabpage_move(int nr)
{
- int n = nr;
- tabpage_T *tp;
+ int n = 1;
+ tabpage_T *tp;
+ tabpage_T *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;
@@ -3304,15 +3314,13 @@ void tabpage_move(int nr)
tp->tp_next = curtab->tp_next;
}
- /* Re-insert it at the specified position. */
- if (n <= 0) {
+ // Re-insert it at the specified position.
+ 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. */
diff --git a/test/functional/legacy/062_tab_pages_spec.lua b/test/functional/legacy/062_tab_pages_spec.lua
index 6bbb06f9a7..f1c8b8d58b 100644
--- a/test/functional/legacy/062_tab_pages_spec.lua
+++ b/test/functional/legacy/062_tab_pages_spec.lua
@@ -86,21 +86,35 @@ describe('tab pages', function()
feed('1gt')
eq(1, eval('tabpagenr()'))
execute('tabmove 5')
- eq(6, eval('tabpagenr()'))
- execute('tabmove -2')
+ eq(5, eval('tabpagenr()'))
+ execute('.tabmove')
+ eq(5, eval('tabpagenr()'))
+ execute('tabmove -')
eq(4, eval('tabpagenr()'))
+ execute('tabmove +')
+ eq(5, eval('tabpagenr()'))
+ execute('tabmove -2')
+ eq(3, eval('tabpagenr()'))
execute('tabmove +4')
- eq(8, eval('tabpagenr()'))
+ eq(7, eval('tabpagenr()'))
execute('tabmove')
eq(10, eval('tabpagenr()'))
execute('tabmove -20')
eq(1, eval('tabpagenr()'))
execute('tabmove +20')
eq(10, eval('tabpagenr()'))
+ execute('0tabmove')
+ eq(1, eval('tabpagenr()'))
+ execute('$tabmove')
+ eq(10, eval('tabpagenr()'))
+ execute('tabmove 0')
+ eq(1, eval('tabpagenr()'))
+ execute('tabmove $')
+ eq(10, eval('tabpagenr()'))
execute('3tabmove')
eq(4, eval('tabpagenr()'))
execute('7tabmove 5')
- eq(6, eval('tabpagenr()'))
+ eq(5, eval('tabpagenr()'))
execute('let a="No error caught."')
execute('try')
execute('tabmove foo')