updated for version 7.0205
diff --git a/src/diff.c b/src/diff.c
index b28e127..d5cb97c 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -974,6 +974,9 @@
 #ifdef FEAT_GUI
     need_mouse_correct = TRUE;
 #endif
+    /* don't use a new tab page, each tab page has its own diffs */
+    cmdmod.tab = 0;
+
     if (win_split(0, 0) != FAIL)
     {
 	/* Pretend it was a ":split fname" command */
@@ -1031,6 +1034,9 @@
 #ifdef FEAT_GUI
     need_mouse_correct = TRUE;
 #endif
+    /* don't use a new tab page, each tab page has its own diffs */
+    cmdmod.tab = 0;
+
     if (win_split(0, 0) != FAIL)
     {
 	/* Pretend it was a ":split fname" command */
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 73bf420..df6273f 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -155,6 +155,9 @@
 static void	ex_stag __ARGS((exarg_T *eap));
 static void	ex_tabclose __ARGS((exarg_T *eap));
 static void	ex_tabonly __ARGS((exarg_T *eap));
+static void	ex_tabnext __ARGS((exarg_T *eap));
+static void	ex_tabprevious __ARGS((exarg_T *eap));
+static void	ex_tabmove __ARGS((exarg_T *eap));
 static void	ex_tabs __ARGS((exarg_T *eap));
 #else
 # define ex_close		ex_ni
@@ -163,7 +166,9 @@
 # define ex_resize		ex_ni
 # define ex_splitview		ex_ni
 # define ex_stag		ex_ni
-# define ex_tab			ex_ni
+# define ex_tabnext		ex_ni
+# define ex_tabprevious		ex_ni
+# define ex_tabmove		ex_ni
 # define ex_tabs		ex_ni
 # define ex_tabclose		ex_ni
 # define ex_tabonly		ex_ni
@@ -1857,7 +1862,25 @@
 			}
 			continue;
 
-	    case 't':	if (!checkforcmd(&ea.cmd, "topleft", 2))
+	    case 't':	if (checkforcmd(&p, "tab", 3))
+			{
+#ifdef FEAT_WINDOWS
+			    tabpage_T	*tp;
+
+			    if (vim_isdigit(*ea.cmd))
+				cmdmod.tab = atoi((char *)ea.cmd) + 1;
+			    else
+			    {
+				cmdmod.tab = 2;
+				for (tp = first_tabpage; tp != curtab;
+							     tp = tp->tp_next)
+				    ++cmdmod.tab;
+			    }
+			    ea.cmd = p;
+#endif
+			    continue;
+			}
+			if (!checkforcmd(&ea.cmd, "topleft", 2))
 			    break;
 #ifdef FEAT_WINDOWS
 			cmdmod.split |= WSP_TOP;
@@ -2380,7 +2403,7 @@
     {
 	n = getdigits(&ea.arg);
 	ea.arg = skipwhite(ea.arg);
-	if (n <= 0 && !ni)
+	if (n <= 0 && !ni && (ea.argt & ZEROR) == 0)
 	{
 	    errormsg = (char_u *)_(e_zerocount);
 	    goto doend;
@@ -6957,7 +6980,7 @@
 	    || eap->cmdidx == CMD_tabfind
 	    || eap->cmdidx == CMD_tabnew)
     {
-	if (win_new_tabpage() != FAIL)
+	if (win_new_tabpage(cmdmod.tab) != FAIL)
 	{
 	    do_exedit(eap, NULL);
 
@@ -6998,13 +7021,48 @@
 }
 
 /*
- * :tab command
+ * Open a new tab page.
  */
     void
-ex_tab(eap)
+tabpage_new()
+{
+    exarg_T	ea;
+
+    vim_memset(&ea, 0, sizeof(ea));
+    ea.cmdidx = CMD_tabnew;
+    ea.cmd = (char_u *)"tabn";
+    ea.arg = (char_u *)"";
+    ex_splitview(&ea);
+}
+
+/*
+ * :tabnext command
+ */
+    static void
+ex_tabnext(eap)
     exarg_T	*eap;
 {
-    goto_tabpage((int)eap->line2);
+    goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2);
+}
+
+/*
+ * :tabprevious and :tabNext command
+ */
+    static void
+ex_tabprevious(eap)
+    exarg_T	*eap;
+{
+    goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2);
+}
+
+/*
+ * :tabmove command
+ */
+    static void
+ex_tabmove(eap)
+    exarg_T	*eap;
+{
+    tabpage_move(eap->addr_count == 0 ? 9999 : (int)eap->line2);
 }
 
 /*
@@ -7035,7 +7093,9 @@
 	    wp = tp->tp_firstwin;
 	for ( ; wp != NULL && !got_int; wp = wp->w_next)
 	{
-	    msg_puts((char_u *)"\n  ");
+	    msg_putchar('\n');
+	    msg_putchar(wp == curwin ? '>' : ' ');
+	    msg_putchar(' ');
 	    msg_putchar(bufIsChanged(wp->w_buffer) ? '+' : ' ');
 	    msg_putchar(' ');
 	    if (buf_spname(wp->w_buffer) != NULL)
diff --git a/src/normal.c b/src/normal.c
index 07857f5..4f4ffa9 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -2437,13 +2437,23 @@
 	    c1 = TabPageIdxs[mouse_col];
 	    if (c1 >= 0)
 	    {
-		/* Go to specified tab page, or next one if not clicking on a
-		 * label. */
-		goto_tabpage(c1);
-
-		/* It's like clicking on the status line of a window. */
-		if (curwin != old_curwin)
+		if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
+		{
+		    /* double click opens new page */
 		    end_visual_mode();
+		    tabpage_new();
+		    tabpage_move(c1 == 0 ? 9999 : c1 - 1);
+		}
+		else
+		{
+		    /* Go to specified tab page, or next one if not clicking
+		     * on a label. */
+		    goto_tabpage(c1);
+
+		    /* It's like clicking on the status line of a window. */
+		    if (curwin != old_curwin)
+			end_visual_mode();
+		}
 	    }
 	    else if (c1 < 0)
 	    {
@@ -7895,6 +7905,9 @@
     case 't':
 	goto_tabpage((int)cap->count0);
 	break;
+    case 'T':
+	goto_tabpage(-(int)cap->count1);
+	break;
 #endif
 
     default:
diff --git a/src/os_vms_conf.h b/src/os_vms_conf.h
index 0064608..2ede37d 100644
--- a/src/os_vms_conf.h
+++ b/src/os_vms_conf.h
@@ -106,6 +106,7 @@
 #define HAVE_FSYNC
 #define HAVE_GETPWUID
 #define HAVE_GETPWNAM
+#define HAVE_STDARG_H
 #define	HAVE_STDLIB_H
 #define	HAVE_STRING_H
 #define	HAVE_ERRNO_H
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index a171e97..94e1393 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -35,8 +35,7 @@
 void alist_add __ARGS((alist_T *al, char_u *fname, int set_fnum));
 void alist_slash_adjust __ARGS((void));
 void ex_splitview __ARGS((exarg_T *eap));
-void ex_tabedit __ARGS((exarg_T *eap));
-void ex_tab __ARGS((exarg_T *eap));
+void tabpage_new __ARGS((void));
 void do_exedit __ARGS((exarg_T *eap, win_T *old_curwin));
 void free_cd_dir __ARGS((void));
 void do_sleep __ARGS((long msec));
diff --git a/src/quickfix.c b/src/quickfix.c
index a29f067..7319e80 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1472,14 +1472,17 @@
     /*
      * For ":helpgrep" find a help window or open one.
      */
-    if (qf_ptr->qf_type == 1 && !curwin->w_buffer->b_help)
+    if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0))
     {
 	win_T	*wp;
 	int	n;
 
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
-	    if (wp->w_buffer != NULL && wp->w_buffer->b_help)
-		break;
+	if (cmdmod.tab != 0)
+	    wp = NULL;
+	else
+	    for (wp = firstwin; wp != NULL; wp = wp->w_next)
+		if (wp->w_buffer != NULL && wp->w_buffer->b_help)
+		    break;
 	if (wp != NULL && wp->w_buffer->b_nwindows > 0)
 	    win_enter(wp, TRUE);
 	else
@@ -2182,6 +2185,7 @@
     qf_info_T	*qi = &ql_info;
     int		height;
     win_T	*win;
+    tabpage_T	*prevtab = curtab;
 
     if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
     {
@@ -2210,7 +2214,7 @@
      */
     win = qf_find_win(qi);
 
-    if (win != NULL)
+    if (win != NULL && cmdmod.tab == 0)
 	win_goto(win);
     else
     {
@@ -2247,10 +2251,13 @@
 	set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
 	set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL);
 
+	/* Only set the height when still in the same tab page and there is no
+	 * window to the side. */
+	if (curtab == prevtab
 #ifdef FEAT_VERTSPLIT
-	/* Only set the height when there is no window to the side. */
-	if (curwin->w_width == Columns)
+		&& curwin->w_width == Columns
 #endif
+	   )
 	    win_setheight(height);
 	curwin->w_p_wfh = TRUE;	    /* set 'winfixheight' */
 	if (win_valid(win))
diff --git a/src/tag.c b/src/tag.c
index ed2889e..8cef850 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -3076,8 +3076,9 @@
 	}
     }
 
-    /* if it was a CTRL-W CTRL-] command split window now */
-    if (postponed_split)
+    /* If it was a CTRL-W CTRL-] command split window now.  For ":tab tag"
+     * open a new tab page. */
+    if (postponed_split || cmdmod.tab != 0)
     {
 	win_split(postponed_split > 0 ? postponed_split : 0,
 						       postponed_split_flags);
diff --git a/src/window.c b/src/window.c
index 548113d..c116dfc 100644
--- a/src/window.c
+++ b/src/window.c
@@ -622,6 +622,10 @@
     int		size;
     int		flags;
 {
+    /* When the ":tab" modifier was used open a new tab page instead. */
+    if (may_open_tabpage() == OK)
+	return OK;
+
     /* Add flags from ":vertical", ":topleft" and ":botright". */
     flags |= cmdmod.split;
     if ((flags & WSP_TOP) && (flags & WSP_BOT))
@@ -2303,14 +2307,13 @@
 {
     tabpage_T	*tp;
 
-    /* Use the next tab page if we are currently at the first one. */
-    if (curtab == first_tabpage)
+    /* Use the next tab page if possible. */
+    if (curtab->tp_next != NULL)
 	return curtab->tp_next;
 
-    /* Find the previous tab page. */
-    for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next)
-	if (tp->tp_next == curtab)
-	    break;
+    /* Find the last but one tab page. */
+    for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next)
+	;
     return tp;
 }
 
@@ -2990,14 +2993,17 @@
 /*
  * Create a new Tab page with one window.
  * It will edit the current buffer, like after ":split".
- * Put it just after the current Tab page.
+ * When "after" is 0 put it just after the current Tab page.
+ * Otherwise put it just before tab page "after".
  * Return FAIL or OK.
  */
     int
-win_new_tabpage()
+win_new_tabpage(after)
+    int		after;
 {
     tabpage_T	*tp = curtab;
     tabpage_T	*newtp;
+    int		n;
 
     newtp = alloc_tabpage();
     if (newtp == NULL)
@@ -3015,8 +3021,25 @@
     if (win_alloc_firstwin(tp->tp_curwin) == OK)
     {
 	/* Make the new Tab page the new topframe. */
-	newtp->tp_next = tp->tp_next;
-	tp->tp_next = newtp;
+	if (after == 1)
+	{
+	    /* New tab page becomes the first one. */
+	    newtp->tp_next = first_tabpage;
+	    first_tabpage = newtp;
+	}
+	else
+	{
+	    if (after > 0)
+	    {
+		/* Put new tab page before tab page "after". */
+		n = 2;
+		for (tp = first_tabpage; tp->tp_next != NULL
+					       && n < after; tp = tp->tp_next)
+		    ++n;
+	    }
+	    newtp->tp_next = tp->tp_next;
+	    tp->tp_next = newtp;
+	}
 	win_init_size();
 	firstwin->w_winrow = tabpageline_height();
 
@@ -3036,6 +3059,24 @@
 }
 
 /*
+ * Open a new tab page if ":tab cmd" was used.  It will edit the same buffer,
+ * like with ":split".
+ * Returns OK if a new tab page was created, FAIL otherwise.
+ */
+    int
+may_open_tabpage()
+{
+    int		n = cmdmod.tab;
+
+    if (cmdmod.tab != 0)
+    {
+	cmdmod.tab = 0;	    /* reset it to avoid doing it twice */
+	return win_new_tabpage(n);
+    }
+    return FAIL;
+}
+
+/*
  * Create up to "maxcount" tabpages with empty windows.
  * Returns the number of resulting tab pages.
  */
@@ -3059,7 +3100,7 @@
 #endif
 
     for (todo = count - 1; todo > 0; --todo)
-	if (win_new_tabpage() == FAIL)
+	if (win_new_tabpage(0) == FAIL)
 	    break;
 
 #ifdef FEAT_AUTOCMD
@@ -3212,6 +3253,7 @@
     int	    n;
 {
     tabpage_T	*tp;
+    tabpage_T	*ttp;
     int		i;
 
     /* If there is only one it can't work. */
@@ -3230,6 +3272,19 @@
 	else
 	    tp = curtab->tp_next;
     }
+    else if (n < 0)
+    {
+	/* "gT": go to previous tab page, wrap around end.  "N gT" repeats
+	 * this N times. */
+	ttp = curtab;
+	for (i = n; i < 0; ++i)
+	{
+	    for (tp = first_tabpage; tp->tp_next != ttp && tp->tp_next != NULL;
+		    tp = tp->tp_next)
+		;
+	    ttp = tp;
+	}
+    }
     else
     {
 	/* Go to tab page "n". */
@@ -3243,7 +3298,7 @@
 	}
     }
 
-    if (leave_tabpage(tp->tp_curwin->w_buffer) == OK)
+    if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer) == OK)
     {
 	if (valid_tabpage(tp))
 	    enter_tabpage(tp, curbuf);
@@ -3253,6 +3308,51 @@
 }
 
 /*
+ * Move the current tab page to before tab page "nr".
+ */
+    void
+tabpage_move(nr)
+    int		nr;
+{
+    int		n = nr;
+    tabpage_T	*tp;
+
+    if (first_tabpage->tp_next == NULL)
+	return;
+
+    /* Remove the current tab page from the list of tab pages. */
+    if (curtab == first_tabpage)
+	first_tabpage = curtab->tp_next;
+    else
+    {
+	for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+	    if (tp->tp_next == curtab)
+		break;
+	if (tp == NULL)	/* "cannot happen" */
+	    return;
+	tp->tp_next = curtab->tp_next;
+    }
+
+    /* Re-insert it at the specified position. */
+    if (n == 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;
+    }
+
+    /* Need to redraw the tabline.  Tab page contents doesn't change. */
+    redraw_tabline = TRUE;
+}
+
+
+/*
  * Go to another window.
  * When jumping to another buffer, stop Visual mode.  Do this before
  * changing windows so we can yank the selection into the '*' register.