updated for version 7.0206
diff --git a/src/Makefile b/src/Makefile
index 1cdfd74..8ff3e3b 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -548,8 +548,8 @@
 #PROFILE_LIBS = -lccmalloc
 
 # MAC OS X platform
-#MAC_OSX_ARCH = -arch ppc
-MAC_OSX_ARCH = -arch i386 -arch ppc
+MAC_OSX_ARCH = -arch ppc
+#MAC_OSX_ARCH = -arch i386
 
 #####################################################
 ###  Specific systems, check if yours is listed!  ### {{{
diff --git a/src/auto/configure b/src/auto/configure
index 05897e2..41245b5 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -2780,7 +2780,7 @@
   test "$GCC" = yes && CFLAGS="-O2 -fno-strength-reduce -Wall"
 fi
 if test "$GCC" = yes; then
-  gccversion=`"$CC" --version | sed -e '2,$d;s/^[^0-9]*\([0-9]\.[0-9.]*\).*$/\1/g'`
+  gccversion=`"$CC" --version | sed -e '2,$d;s/^[^0-9]*\(darwin.[^0-9]*\)*\([0-9]\.[0-9.]*\).*$/\2/g'`
     if test "$gccversion" = "3.0.1" -o "$gccversion" = "3.0.2" -o "$gccversion" = "4.0.1"; then
     echo 'GCC 34.0.12 has a bug in the optimizer, disabling "-O#"'
     CFLAGS=`echo "$CFLAGS" | sed 's/-O[23456789]/-O/'`
@@ -2868,7 +2868,7 @@
     MACOSX=yes
     OS_EXTRA_SCR="os_macosx.c os_mac_conv.c";
     OS_EXTRA_OBJ="objects/os_macosx.o objects/os_mac_conv.o"
-    CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX -I/Developer/Headers/FlatCarbon -no-cpp-precomp"
+        CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX -I/Developer/Headers/FlatCarbon -no-cpp-precomp -arch ppc"
 
                 echo "$as_me:$LINENO: checking for ANSI C header files" >&5
 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
@@ -15087,7 +15087,7 @@
 echo $ECHO_N "checking for GCC 3 or later... $ECHO_C" >&6
 DEPEND_CFLAGS_FILTER=
 if test "$GCC" = yes; then
-  gccmajor=`"$CC" --version | sed -e '2,$d;s/^[^0-9]*\([1-9]\)\.[0-9.]*.*$/\1/g'`
+  gccmajor=`"$CC" --version | sed -e '2,$d;s/^[^0-9]*\(darwin.[^0-9]*\)*\([1-9]\)\.[0-9].*$/\2/g'`
   if test "$gccmajor" -gt "2"; then
     DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
   fi
diff --git a/src/configure.in b/src/configure.in
index 913d3e9..382d1af 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -29,7 +29,7 @@
   test "$GCC" = yes && CFLAGS="-O2 -fno-strength-reduce -Wall"
 fi
 if test "$GCC" = yes; then
-  gccversion=`"$CC" --version | sed -e '2,$d;s/^[[^0-9]]*\([[0-9]]\.[[0-9.]]*\).*$/\1/g'`
+  gccversion=`"$CC" --version | sed -e '2,$d;s/^[[^0-9]]*\(darwin.[[^0-9]]*\)*\([[0-9]]\.[[0-9.]]*\).*$/\2/g'`
   dnl version 4.0.1 was reported to cause trouble on Macintosh by Marcin Dalecki
   if test "$gccversion" = "3.0.1" -o "$gccversion" = "3.0.2" -o "$gccversion" = "4.0.1"; then
     echo 'GCC [34].0.[12] has a bug in the optimizer, disabling "-O#"'
@@ -106,7 +106,8 @@
     MACOSX=yes
     OS_EXTRA_SCR="os_macosx.c os_mac_conv.c";
     OS_EXTRA_OBJ="objects/os_macosx.o objects/os_mac_conv.o"
-    CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX -I/Developer/Headers/FlatCarbon -no-cpp-precomp -arch i386 -arch ppc"
+    dnl TODO: use -arch i386 on Intel machines
+    CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX -I/Developer/Headers/FlatCarbon -no-cpp-precomp -arch ppc"
 
     dnl If Carbon is found, assume we don't want X11
     dnl unless it was specifically asked for (--with-x)
@@ -2757,10 +2758,12 @@
 dnl gcc 3.1 changed the meaning of -MM.  The only solution appears to be to
 dnl use "-isystem" instead of "-I" for all non-Vim include dirs.
 dnl But only when making dependencies, cproto and lint don't take "-isystem".
+dnl Mac gcc returns "powerpc-apple-darwin8-gcc-4.0.1 (GCC)...", need to allow
+dnl the number before the version number.
 AC_MSG_CHECKING(for GCC 3 or later)
 DEPEND_CFLAGS_FILTER=
 if test "$GCC" = yes; then
-  gccmajor=`"$CC" --version | sed -e '2,$d;s/^[[^0-9]]*\([[1-9]]\)\.[[0-9.]]*.*$/\1/g'`
+  gccmajor=`"$CC" --version | sed -e '2,$d;s/^[[^0-9]]*\(darwin.[[^0-9]]*\)*\([[1-9]]\)\.[[0-9]].*$/\2/g'`
   if test "$gccmajor" -gt "2"; then
     DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
   fi
diff --git a/src/eval.c b/src/eval.c
index fef09d0..52525e6 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -14934,7 +14934,6 @@
 {
     int		nr = 1;
 #ifdef FEAT_WINDOWS
-    tabpage_T	*tp;
     char_u	*arg;
 
     if (argvars[0].v_type != VAR_UNKNOWN)
@@ -14944,15 +14943,13 @@
 	if (arg != NULL)
 	{
 	    if (STRCMP(arg, "$") == 0)
-		for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
-		    ++nr;
+		nr = tabpage_index(NULL);
 	    else
 		EMSG2(_(e_invexpr2), arg);
 	}
     }
     else
-	for (tp = first_tabpage; tp != curtab; tp = tp->tp_next)
-	    ++nr;
+	nr = tabpage_index(curtab);
 #endif
     rettv->vval.v_number = nr;
 }
@@ -15616,6 +15613,7 @@
 
 /*
  * Translate a String variable into a position.
+ * Returns NULL when there is an error.
  */
     static pos_T *
 var2fpos(varp, lnum)
@@ -15626,6 +15624,39 @@
     static pos_T	pos;
     pos_T	*pp;
 
+    /* Argument can be [lnum, col]. */
+    if (varp->v_type == VAR_LIST)
+    {
+	list_T		*l;
+	listitem_T	*li;
+	int		len;
+
+	l = varp->vval.v_list;
+	if (l == NULL)
+	    return NULL;
+
+	/* Get the line number */
+	li = list_find(l, 0L);
+	if (li == NULL)
+	    return NULL;
+	pos.lnum = get_tv_number(&li->li_tv);
+	if (pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
+	    return NULL;	/* invalid line number */
+
+	/* Get the column number */
+	li = list_find(l, 1L);
+	if (li == NULL)
+	    return NULL;
+	pos.col = get_tv_number(&li->li_tv);
+	len = (long)STRLEN(ml_get(pos.lnum));
+	if (pos.col <= 0 || ((len == 0 && pos.col > 1)
+					       || (len > 0 && pos.col > len)))
+	    return NULL;	/* invalid column number */
+
+	pos.col--;
+	return &pos;
+    }
+
     name = get_tv_string_chk(varp);
     if (name == NULL)
 	return NULL;
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 71a0e2a..393f714 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -881,22 +881,30 @@
 			NEEDARG|EXTRA|NOTRLCOM),
 EX(CMD_tabclose,	"tabclose",	ex_tabclose,
 			RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN),
+EX(CMD_tabdo,		"tabdo",	ex_listdo,
+			NEEDARG|EXTRA|NOTRLCOM),
 EX(CMD_tabedit,		"tabedit",	ex_splitview,
 			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
 EX(CMD_tabfind,		"tabfind",	ex_splitview,
 			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|NEEDARG|TRLBAR),
+EX(CMD_tabfirst,	"tabfirst",	ex_tabnext,
+			TRLBAR),
 EX(CMD_tabmove,		"tabmove",	ex_tabmove,
 			RANGE|NOTADR|COUNT|TRLBAR|ZEROR),
+EX(CMD_tablast,		"tablast",	ex_tabnext,
+			TRLBAR),
 EX(CMD_tabnext,		"tabnext",	ex_tabnext,
 			RANGE|NOTADR|COUNT|TRLBAR),
 EX(CMD_tabnew,		"tabnew",	ex_splitview,
 			BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
 EX(CMD_tabonly,		"tabonly",	ex_tabonly,
 			TRLBAR|CMDWIN),
-EX(CMD_tabprevious,	"tabprevious",	ex_tabprevious,
+EX(CMD_tabprevious,	"tabprevious",	ex_tabnext,
 			RANGE|NOTADR|COUNT|TRLBAR),
-EX(CMD_tabNext,		"tabNext",	ex_tabprevious,
+EX(CMD_tabNext,		"tabNext",	ex_tabnext,
 			RANGE|NOTADR|COUNT|TRLBAR),
+EX(CMD_tabrewind,	"tabrewind",	ex_tabnext,
+			TRLBAR),
 EX(CMD_tabs,		"tabs",		ex_tabs,
 			TRLBAR|CMDWIN),
 EX(CMD_tcl,		"tcl",		ex_tcl,
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 416fd3e..0d7188a 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -2155,7 +2155,7 @@
 }
 
 /*
- * ":argdo", ":windo", ":bufdo"
+ * ":argdo", ":windo", ":bufdo", ":tabdo"
  */
     void
 ex_listdo(eap)
@@ -2163,7 +2163,8 @@
 {
     int		i;
 #ifdef FEAT_WINDOWS
-    win_T	*win;
+    win_T	*wp;
+    tabpage_T	*tp;
 #endif
     buf_T	*buf;
     int		next_fnum = 0;
@@ -2188,13 +2189,15 @@
 #endif
 
     if (eap->cmdidx == CMD_windo
+	    || eap->cmdidx == CMD_tabdo
 	    || P_HID(curbuf)
 	    || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE))
     {
 	/* start at the first argument/window/buffer */
 	i = 0;
 #ifdef FEAT_WINDOWS
-	win = firstwin;
+	wp = firstwin;
+	tp = first_tabpage;
 #endif
 	/* set pcmark now */
 	if (eap->cmdidx == CMD_bufdo)
@@ -2229,11 +2232,19 @@
 #ifdef FEAT_WINDOWS
 	    else if (eap->cmdidx == CMD_windo)
 	    {
-		/* go to window "win" */
-		if (!win_valid(win))
+		/* go to window "wp" */
+		if (!win_valid(wp))
 		    break;
-		win_goto(win);
-		win = curwin->w_next;
+		win_goto(wp);
+		wp = curwin->w_next;
+	    }
+	    else if (eap->cmdidx == CMD_tabdo)
+	    {
+		/* go to window "tp" */
+		if (!valid_tabpage(tp))
+		    break;
+		goto_tabpage_tp(tp);
+		tp = tp->tp_next;
 	    }
 #endif
 	    else if (eap->cmdidx == CMD_bufdo)
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index df6273f..74998d9 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -156,7 +156,6 @@
 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
@@ -167,7 +166,6 @@
 # define ex_splitview		ex_ni
 # define ex_stag		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
@@ -1865,17 +1863,10 @@
 	    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;
-			    }
+				cmdmod.tab = tabpage_index(curtab) + 1;
 			    ea.cmd = p;
 #endif
 			    continue;
@@ -6242,7 +6233,7 @@
     exarg_T	*eap;
 {
     tabpage_T	*tp;
-    int		h = tabpageline_height();
+    int		h = tabline_height();
 
 # ifdef FEAT_CMDWIN
     if (cmdwin_type != 0)
@@ -6271,7 +6262,7 @@
 		tabpage_close(eap->forceit);
 	}
 
-    if (h != tabpageline_height())
+    if (h != tabline_height())
 	shell_new_rows();
 }
 
@@ -6284,7 +6275,7 @@
 {
     tabpage_T	*tp;
     int		done;
-    int		h = tabpageline_height();
+    int		h = tabline_height();
 
 # ifdef FEAT_CMDWIN
     if (cmdwin_type != 0)
@@ -6314,7 +6305,7 @@
 	    }
 	}
 
-    if (h != tabpageline_height())
+    if (h != tabline_height())
 	shell_new_rows();
 }
 
@@ -7042,17 +7033,23 @@
 ex_tabnext(eap)
     exarg_T	*eap;
 {
-    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);
+    switch (eap->cmdidx)
+    {
+	case CMD_tabfirst:
+	case CMD_tabrewind:
+	    goto_tabpage(1);
+	    break;
+	case CMD_tablast:
+	    goto_tabpage(9999);
+	    break;
+	case CMD_tabprevious:
+	case CMD_tabNext:
+	    goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2);
+	    break;
+	default: /* CMD_tabnext */
+	    goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2);
+	    break;
+    }
 }
 
 /*
diff --git a/src/feature.h b/src/feature.h
index efe7915..e2d9013 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -730,6 +730,13 @@
 #endif
 
 /*
+ * GUI tabline
+ */
+#if defined(FEAT_GUI_GTK) && defined(HAVE_GTK2) && defined(FEAT_WINDOWS)
+# define FEAT_GUI_TABLINE
+#endif
+
+/*
  * +browse		":browse" command.
  */
 #if defined(FEAT_NORMAL) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC))
diff --git a/src/globals.h b/src/globals.h
index d46b10c..1263e81 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -435,6 +435,10 @@
 /* Set to TRUE after adding/removing menus to ensure they are updated */
 EXTERN int force_menu_update INIT(= FALSE);
 # endif
+# ifdef FEAT_GUI_TABLINE
+/* Tab in tab pages line just selected, set by check_termcode() */
+EXTERN int	    current_tab;
+# endif
 
 /* Scrollbar moved and new value, set by check_termcode() */
 EXTERN int	current_scrollbar;
diff --git a/src/gui.c b/src/gui.c
index 3a1b31c..9b97ffd 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -26,6 +26,9 @@
 static void gui_delete_lines __ARGS((int row, int count));
 static void gui_insert_lines __ARGS((int row, int count));
 static void fill_mouse_coord __ARGS((char_u *p, int col, int row));
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+static int gui_has_tabline __ARGS((void));
+#endif
 static void gui_do_scrollbar __ARGS((win_T *wp, int which, int enable));
 static colnr_T scroll_line_len __ARGS((linenr_T lnum));
 static void gui_update_horiz_scrollbar __ARGS((int));
@@ -1410,7 +1413,7 @@
     min_width = base_width + MIN_COLUMNS * gui.char_width;
     min_height = base_height + MIN_LINES * gui.char_height;
 # ifdef FEAT_WINDOWS
-    min_height += tabpageline_height() * gui.char_height;
+    min_height += tabline_height() * gui.char_height;
 # endif
 
     gui_mch_set_shellsize(width, height, min_width, min_height,
@@ -3081,7 +3084,7 @@
 
 /*
  * Set which components are present.
- * If "oldval" is not NULL, "oldval" is the previous value, the new * value is
+ * If "oldval" is not NULL, "oldval" is the previous value, the new value is
  * in p_go.
  */
 /*ARGSUSED*/
@@ -3096,6 +3099,10 @@
     static int	prev_toolbar = -1;
     int		using_toolbar = FALSE;
 #endif
+#ifdef FEAT_GUI_TABLINE
+    static int	prev_has_tabline = FALSE;
+    int		using_tabline;
+#endif
 #ifdef FEAT_FOOTER
     static int	prev_footer = -1;
     int		using_footer = FALSE;
@@ -3185,10 +3192,27 @@
 		/* Ignore options that are not supported */
 		break;
 	}
+
     if (gui.in_use)
     {
 	need_set_size = FALSE;
 	fix_size = FALSE;
+
+#ifdef FEAT_GUI_TABLINE
+	/* Update the tab line, it may appear or disappear. */
+	using_tabline = gui_has_tabline();
+	if (prev_has_tabline != using_tabline)
+	{
+	    prev_has_tabline = using_tabline;
+	    gui_update_tabline();
+	    need_set_size = TRUE;
+	    if (using_tabline)
+		fix_size = TRUE;
+	    if (!gui_use_tabline())
+		redraw_tabline = TRUE;    /* may draw non-GUI tab line */
+	}
+#endif
+
 	for (i = 0; i < 3; i++)
 	{
 	    if (gui.which_scrollbars[i] != prev_which_scrollbars[i])
@@ -3281,6 +3305,82 @@
     }
 }
 
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+/*
+ * Return TRUE if the GUI is taking care of the tabline.
+ * It may still be hidden if 'showtabline' is zero.
+ */
+    int
+gui_use_tabline()
+{
+    return gui.in_use && vim_strchr(p_go, GO_TABLINE) != NULL;
+}
+
+/*
+ * Return TRUE if the GUI is showing the tabline.
+ * This uses 'showtabline'.
+ */
+    static int
+gui_has_tabline()
+{
+    if (!gui_use_tabline()
+	    || p_stal == 0
+	    || (p_stal == 1 && first_tabpage->tp_next == NULL))
+	return FALSE;
+    return TRUE;
+}
+
+/*
+ * Update the tabline.
+ * This may display/undisplay the tabline and update the labels.
+ */
+    void
+gui_update_tabline()
+{
+    int	    showit = gui_has_tabline();
+
+    if (!gui.starting && starting == 0)
+    {
+	gui_mch_show_tabline(showit);
+	if (showit != 0)
+	    gui_mch_update_tabline();
+    }
+}
+
+/*
+ * Get the label for tab page "tp" into NameBuff[].
+ */
+    void
+get_tabline_label(tp)
+    tabpage_T	*tp;
+{
+    int		modified = FALSE;
+    char_u	buf[40];
+    int		wincount;
+    win_T	*wp;
+
+    /* Get the buffer name into NameBuff[] */
+    get_trans_bufname(tp == curtab ? curbuf : tp->tp_curwin->w_buffer);
+
+    wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
+    for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount)
+	if (bufIsChanged(wp->w_buffer))
+	    modified = TRUE;
+    if (modified || wincount > 1)
+    {
+	if (wincount > 1)
+	    vim_snprintf((char *)buf, sizeof(buf), "%d", wincount);
+	else
+	    buf[0] = NUL;
+	if (modified)
+	    STRCAT(buf, "+");
+	STRCAT(buf, " ");
+	mch_memmove(NameBuff + STRLEN(buf), NameBuff, STRLEN(NameBuff) + 1);
+	mch_memmove(NameBuff, buf, STRLEN(buf));
+    }
+}
+
+#endif
 
 /*
  * Scrollbar stuff:
diff --git a/src/gui.h b/src/gui.h
index c706302..f1a9e64 100644
--- a/src/gui.h
+++ b/src/gui.h
@@ -393,6 +393,7 @@
     PangoContext     *text_context; /* the context used for all text */
     PangoFont	     *ascii_font;   /* cached font for ASCII strings */
     PangoGlyphString *ascii_glyphs; /* cached code point -> glyph map */
+    GtkWidget	*tabline;	    /* tab pages line handle */
 # endif
 
     GtkAccelGroup *accel_group;
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index c608f9d..4cae9a1 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -2827,6 +2827,145 @@
     return TRUE;
 }
 
+#if defined(FEAT_MENU) || defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE)
+    static int
+get_item_dimensions(GtkWidget *widget, GtkOrientation orientation)
+{
+    GtkOrientation item_orientation = GTK_ORIENTATION_HORIZONTAL;
+
+#ifdef FEAT_GUI_GNOME
+    if (using_gnome && widget != NULL)
+    {
+# ifdef HAVE_GTK2
+	BonoboDockItem *dockitem;
+
+	widget	 = gtk_widget_get_parent(widget);
+	dockitem = BONOBO_DOCK_ITEM(widget);
+
+	if (dockitem == NULL || dockitem->is_floating)
+	    return 0;
+	item_orientation = bonobo_dock_item_get_orientation(dockitem);
+# else
+	GnomeDockItem *dockitem;
+
+	widget	 = widget->parent;
+	dockitem = GNOME_DOCK_ITEM(widget);
+
+	if (dockitem == NULL || dockitem->is_floating)
+	    return 0;
+	item_orientation = gnome_dock_item_get_orientation(dockitem);
+# endif
+    }
+#endif
+    if (widget != NULL
+	    && item_orientation == orientation
+	    && GTK_WIDGET_REALIZED(widget)
+	    && GTK_WIDGET_VISIBLE(widget))
+    {
+	if (orientation == GTK_ORIENTATION_HORIZONTAL)
+	    return widget->allocation.height;
+	else
+	    return widget->allocation.width;
+    }
+    return 0;
+}
+#endif
+
+    static int
+get_menu_tool_width(void)
+{
+    int width = 0;
+
+#ifdef FEAT_GUI_GNOME /* these are never vertical without GNOME */
+# ifdef FEAT_MENU
+    width += get_item_dimensions(gui.menubar, GTK_ORIENTATION_VERTICAL);
+# endif
+# ifdef FEAT_TOOLBAR
+    width += get_item_dimensions(gui.toolbar, GTK_ORIENTATION_VERTICAL);
+# endif
+# ifdef FEAT_GUI_TABLINE
+    width += get_item_dimensions(gui.tabline, GTK_ORIENTATION_VERTICAL);
+# endif
+#endif
+
+    return width;
+}
+
+    static int
+get_menu_tool_height(void)
+{
+    int height = 0;
+
+#ifdef FEAT_MENU
+    height += get_item_dimensions(gui.menubar, GTK_ORIENTATION_HORIZONTAL);
+#endif
+#ifdef FEAT_TOOLBAR
+    height += get_item_dimensions(gui.toolbar, GTK_ORIENTATION_HORIZONTAL);
+#endif
+#ifdef FEAT_GUI_TABLINE
+    height += get_item_dimensions(gui.tabline, GTK_ORIENTATION_HORIZONTAL);
+#endif
+
+    return height;
+}
+
+    static void
+update_window_manager_hints(void)
+{
+    static int old_width  = 0;
+    static int old_height = 0;
+    static int old_char_width  = 0;
+    static int old_char_height = 0;
+
+    int width;
+    int height;
+
+    /* This also needs to be done when the main window isn't there yet,
+     * otherwise the hints don't work. */
+    width  = gui_get_base_width();
+    height = gui_get_base_height();
+# ifdef FEAT_MENU
+    height += tabline_height() * gui.char_height;
+# endif
+# ifdef HAVE_GTK2
+    width  += get_menu_tool_width();
+    height += get_menu_tool_height();
+# endif
+
+    /* Avoid an expose event when the size didn't change. */
+    if (width != old_width
+	    || height != old_height
+	    || gui.char_width != old_char_width
+	    || gui.char_height != old_char_height)
+    {
+	GdkGeometry	geometry;
+	GdkWindowHints	geometry_mask;
+
+	geometry.width_inc   = gui.char_width;
+	geometry.height_inc  = gui.char_height;
+	geometry.base_width  = width;
+	geometry.base_height = height;
+	geometry.min_width   = width  + MIN_COLUMNS * gui.char_width;
+	geometry.min_height  = height + MIN_LINES   * gui.char_height;
+	geometry_mask	     = GDK_HINT_BASE_SIZE|GDK_HINT_RESIZE_INC
+			       |GDK_HINT_MIN_SIZE;
+# ifdef HAVE_GTK2
+	/* Using gui.formwin as geometry widget doesn't work as expected
+	 * with GTK+ 2 -- dunno why.  Presumably all the resizing hacks
+	 * in Vim confuse GTK+. */
+	gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.mainwin,
+				      &geometry, geometry_mask);
+# else
+	gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.formwin,
+				      &geometry, geometry_mask);
+# endif
+	old_width  = width;
+	old_height = height;
+	old_char_width	= gui.char_width;
+	old_char_height = gui.char_height;
+    }
+}
+
 #ifdef FEAT_TOOLBAR
 
 # ifdef HAVE_GTK2
@@ -2920,6 +3059,122 @@
 
 #endif /* FEAT_TOOLBAR */
 
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+static int ignore_tabline_evt = FALSE;
+
+/*
+ * Handle selecting one of the tabs.
+ */
+/*ARGSUSED*/
+    static void
+on_select_tab(
+	GtkNotebook	*notebook,
+	GtkNotebookPage *page,
+	gint		index,
+	gpointer	data)
+{
+    static char_u string[3];
+
+    if (!ignore_tabline_evt)
+    {
+	string[0] = CSI;
+	string[1] = KS_TABLINE;
+	string[2] = KE_FILLER;
+	add_to_input_buf(string, 3);
+	string[0] = index + 1;
+	add_to_input_buf_csi(string, 1);
+
+	if (gtk_main_level() > 0)
+	    gtk_main_quit();
+    }
+}
+
+/*
+ * Show or hide the tabline.
+ */
+    void
+gui_mch_show_tabline(int showit)
+{
+    if (gui.tabline == NULL)
+	return;
+
+    if (!showit != !gtk_notebook_get_show_tabs(GTK_NOTEBOOK(gui.tabline)))
+    {
+	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), showit);
+	update_window_manager_hints();
+    }
+}
+
+/*
+ * Update the labels of the tabline.
+ */
+    void
+gui_mch_update_tabline(void)
+{
+    GtkWidget	    *page;
+    GtkWidget	    *label;
+    tabpage_T	    *tp;
+    int		    nr = 0;
+    int		    curtabidx = 0;
+
+    if (gui.tabline == NULL)
+	return;
+
+    ignore_tabline_evt = TRUE;
+
+    /* Add a label for each tab page.  They all contain the same text area. */
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr)
+    {
+	if (tp == curtab)
+	    curtabidx = nr;
+
+	page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr);
+	if (page == NULL)
+	{
+	    /* Add notebook page */
+	    page = gtk_vbox_new(FALSE, 0);
+	    gtk_widget_show(page);
+	    label = gtk_label_new("-Empty-");
+	    gtk_widget_show(label);
+	    gtk_notebook_insert_page(GTK_NOTEBOOK(gui.tabline),
+		    page,
+		    label,
+		    nr++);
+	}
+
+	get_tabline_label(tp);
+	gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(gui.tabline), page,
+						     (const gchar *)NameBuff);
+    }
+
+    /* Remove any old labels. */
+    while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(gui.tabline), nr) != NULL)
+	gtk_notebook_remove_page(GTK_NOTEBOOK(gui.tabline), nr);
+
+    if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != curtabidx)
+        gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), curtabidx);
+
+    ignore_tabline_evt = FALSE;
+}
+
+/*
+ * Set the current tab to "nr".  First tab is 1.
+ */
+    void
+gui_mch_set_curtab(nr)
+    int		nr;
+{
+    if (gui.tabline == NULL)
+	return;
+
+    ignore_tabline_evt = TRUE;
+    if (gtk_notebook_current_page(GTK_NOTEBOOK(gui.tabline)) != nr - 1)
+        gtk_notebook_set_page(GTK_NOTEBOOK(gui.tabline), nr - 1);
+    ignore_tabline_evt = FALSE;
+}
+
+#endif /* FEAT_GUI_TABLINE */
+
 /*
  * Initialize the GUI.	Create all the windows, set up all the callbacks etc.
  * Returns OK for success, FAIL when the GUI can't be started.
@@ -3060,6 +3315,7 @@
     gui.accel_group = gtk_accel_group_get_default();
 #endif
 
+    /* A vertical box holds the menubar, toolbar and main text window. */
     vbox = gtk_vbox_new(FALSE, 0);
 
 #ifdef FEAT_GUI_GNOME
@@ -3194,6 +3450,30 @@
     }
 #endif /* FEAT_TOOLBAR */
 
+#ifdef FEAT_GUI_TABLINE
+    /* Use a Notebook for the tab pages labels.  The labels are hidden by
+     * default. */
+    gui.tabline = gtk_notebook_new();
+    gtk_widget_show(gui.tabline);
+    gtk_box_pack_start(GTK_BOX(vbox), gui.tabline, FALSE, FALSE, 0);
+    gtk_notebook_set_show_border(GTK_NOTEBOOK(gui.tabline), FALSE);
+    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gui.tabline), FALSE);
+
+    {
+	GtkWidget *page, *label;
+
+	/* Add the first tab. */
+	page = gtk_vbox_new(FALSE, 0);
+	gtk_widget_show(page);
+	gtk_container_add(GTK_CONTAINER(gui.tabline), page);
+	label = gtk_label_new("-Empty-");
+	gtk_widget_show(label);
+	gtk_notebook_set_tab_label(GTK_NOTEBOOK(gui.tabline), page, label);
+    }
+    gtk_signal_connect(GTK_OBJECT(gui.tabline), "switch_page",
+		       GTK_SIGNAL_FUNC(on_select_tab), NULL);
+#endif
+
     gui.formwin = gtk_form_new();
     gtk_container_border_width(GTK_CONTAINER(gui.formwin), 0);
     gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK);
@@ -3365,139 +3645,6 @@
     }
 }
 
-#if defined(FEAT_MENU) || defined(FEAT_TOOLBAR)
-    static int
-get_item_dimensions(GtkWidget *widget, GtkOrientation orientation)
-{
-    GtkOrientation item_orientation = GTK_ORIENTATION_HORIZONTAL;
-
-#ifdef FEAT_GUI_GNOME
-    if (using_gnome && widget != NULL)
-    {
-# ifdef HAVE_GTK2
-	BonoboDockItem *dockitem;
-
-	widget	 = gtk_widget_get_parent(widget);
-	dockitem = BONOBO_DOCK_ITEM(widget);
-
-	if (dockitem == NULL || dockitem->is_floating)
-	    return 0;
-	item_orientation = bonobo_dock_item_get_orientation(dockitem);
-# else
-	GnomeDockItem *dockitem;
-
-	widget	 = widget->parent;
-	dockitem = GNOME_DOCK_ITEM(widget);
-
-	if (dockitem == NULL || dockitem->is_floating)
-	    return 0;
-	item_orientation = gnome_dock_item_get_orientation(dockitem);
-# endif
-    }
-#endif
-    if (widget != NULL
-	    && item_orientation == orientation
-	    && GTK_WIDGET_REALIZED(widget)
-	    && GTK_WIDGET_VISIBLE(widget))
-    {
-	if (orientation == GTK_ORIENTATION_HORIZONTAL)
-	    return widget->allocation.height;
-	else
-	    return widget->allocation.width;
-    }
-    return 0;
-}
-#endif
-
-    static int
-get_menu_tool_width(void)
-{
-    int width = 0;
-
-#ifdef FEAT_GUI_GNOME /* these are never vertical without GNOME */
-# ifdef FEAT_MENU
-    width += get_item_dimensions(gui.menubar, GTK_ORIENTATION_VERTICAL);
-# endif
-# ifdef FEAT_TOOLBAR
-    width += get_item_dimensions(gui.toolbar, GTK_ORIENTATION_VERTICAL);
-# endif
-#endif
-
-    return width;
-}
-
-    static int
-get_menu_tool_height(void)
-{
-    int height = 0;
-
-#ifdef FEAT_MENU
-    height += get_item_dimensions(gui.menubar, GTK_ORIENTATION_HORIZONTAL);
-#endif
-#ifdef FEAT_TOOLBAR
-    height += get_item_dimensions(gui.toolbar, GTK_ORIENTATION_HORIZONTAL);
-#endif
-
-    return height;
-}
-
-    static void
-update_window_manager_hints(void)
-{
-    static int old_width  = 0;
-    static int old_height = 0;
-    static int old_char_width  = 0;
-    static int old_char_height = 0;
-
-    int width;
-    int height;
-
-    /* This also needs to be done when the main window isn't there yet,
-     * otherwise the hints don't work. */
-    width  = gui_get_base_width();
-    height = gui_get_base_height();
-# ifdef FEAT_MENU
-    height += tabpageline_height() * gui.char_height;
-# endif
-# ifdef HAVE_GTK2
-    width  += get_menu_tool_width();
-    height += get_menu_tool_height();
-# endif
-
-    /* Avoid an expose event when the size didn't change. */
-    if (width != old_width
-	    || height != old_height
-	    || gui.char_width != old_char_width
-	    || gui.char_height != old_char_height)
-    {
-	GdkGeometry	geometry;
-	GdkWindowHints	geometry_mask;
-
-	geometry.width_inc   = gui.char_width;
-	geometry.height_inc  = gui.char_height;
-	geometry.base_width  = width;
-	geometry.base_height = height;
-	geometry.min_width   = width  + MIN_COLUMNS * gui.char_width;
-	geometry.min_height  = height + MIN_LINES   * gui.char_height;
-	geometry_mask	     = GDK_HINT_BASE_SIZE|GDK_HINT_RESIZE_INC
-			       |GDK_HINT_MIN_SIZE;
-# ifdef HAVE_GTK2
-	/* Using gui.formwin as geometry widget doesn't work as expected
-	 * with GTK+ 2 -- dunno why.  Presumably all the resizing hacks
-	 * in Vim confuse GTK+. */
-	gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.mainwin,
-				      &geometry, geometry_mask);
-# else
-	gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.formwin,
-				      &geometry, geometry_mask);
-# endif
-	old_width  = width;
-	old_height = height;
-	old_char_width	= gui.char_width;
-	old_char_height = gui.char_height;
-    }
-}
-
 /*
  * This signal informs us about the need to rearrange our sub-widgets.
  */
diff --git a/src/keymap.h b/src/keymap.h
index 0aa4474..3ffea93 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -101,6 +101,9 @@
 /* Used for the qnx pterm mouse */
 #define KS_PTERM_MOUSE		241
 
+/* Used for click in a tab pages label. */
+#define KS_TABLINE		240
+
 /*
  * Filler used after KS_SPECIAL and others
  */
@@ -399,6 +402,8 @@
 #define K_SELECT	TERMCAP2KEY(KS_SELECT, KE_FILLER)
 #define K_TEAROFF	TERMCAP2KEY(KS_TEAROFF, KE_FILLER)
 
+#define K_TABLINE	TERMCAP2KEY(KS_TABLINE, KE_FILLER)
+
 /*
  * Symbols for pseudo keys which are translated from the real key symbols
  * above.
diff --git a/src/main.c b/src/main.c
index 705acf5..413ca1f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -880,6 +880,18 @@
     mch_set_winsize_now();	    /* Allow winsize changes from now on */
 #endif
 
+#if defined(FEAT_GUI) && defined(FEAT_WINDOWS)
+    /* When tab pages were created, may need to update the tab pages line and
+     * scrollbars.  This is skipped while creating them. */
+    if (first_tabpage->tp_next != NULL)
+    {
+	out_flush();
+	gui_init_which_components(NULL);
+	gui_update_scrollbars(TRUE);
+    }
+    need_mouse_correct = TRUE;
+#endif
+
     /* If ":startinsert" command used, stuff a dummy command to be able to
      * call normal_cmd(), which will then start Insert mode. */
     if (restart_edit != 0)
diff --git a/src/normal.c b/src/normal.c
index 4f4ffa9..cc9d0d1 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -74,6 +74,9 @@
 static void	nv_ver_scrollbar __ARGS((cmdarg_T *cap));
 static void	nv_hor_scrollbar __ARGS((cmdarg_T *cap));
 #endif
+#ifdef FEAT_GUI_TABLINE
+static void	nv_tabline __ARGS((cmdarg_T *cap));
+#endif
 static void	nv_exmode __ARGS((cmdarg_T *cap));
 static void	nv_colon __ARGS((cmdarg_T *cap));
 static void	nv_ctrlg __ARGS((cmdarg_T *cap));
@@ -418,6 +421,9 @@
     {K_VER_SCROLLBAR, nv_ver_scrollbar, 0,		0},
     {K_HOR_SCROLLBAR, nv_hor_scrollbar, 0,		0},
 #endif
+#ifdef FEAT_GUI_TABLINE
+    {K_TABLINE, nv_tabline,	0,			0},
+#endif
 #ifdef FEAT_FKMAP
     {K_F8,	farsi_fkey,	0,			0},
     {K_F9,	farsi_fkey,	0,			0},
@@ -4977,6 +4983,22 @@
 }
 #endif
 
+#ifdef FEAT_GUI_TABLINE
+/*
+ * Click in GUI tab.
+ */
+    static void
+nv_tabline(cap)
+    cmdarg_T	*cap;
+{
+    if (cap->oap->op_type != OP_NOP)
+	clearopbeep(cap->oap);
+
+    /* Even if an operator was pending, we still want to jump tabs. */
+    goto_tabpage(current_tab);
+}
+#endif
+
 /*
  * "Q" command.
  */
@@ -5329,7 +5351,7 @@
 	    else if (g_cmd)
 		STRCPY(buf, "tj ");
 	    else
-		STRCPY(buf, "ta ");
+		sprintf((char *)buf, "%ldta ", cap->count0);
     }
 
     /*
diff --git a/src/option.c b/src/option.c
index 1925000..d32cf5e 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1099,9 +1099,9 @@
 #if defined(FEAT_GUI)
 			    (char_u *)&p_go, PV_NONE,
 # if defined(UNIX) && !defined(MACOS)
-			    {(char_u *)"agimrLtT", (char_u *)0L}
+			    {(char_u *)"aegimrLtT", (char_u *)0L}
 # else
-			    {(char_u *)"gmrLtT", (char_u *)0L}
+			    {(char_u *)"egmrLtT", (char_u *)0L}
 # endif
 #else
 			    (char_u *)NULL, PV_NONE,
diff --git a/src/option.h b/src/option.h
index ebf154b..54ae889 100644
--- a/src/option.h
+++ b/src/option.h
@@ -223,6 +223,7 @@
 #define GO_ASELML	'A'		/* autoselect modeless selection */
 #define GO_BOT		'b'		/* use bottom scrollbar */
 #define GO_CONDIALOG	'c'		/* use console dialog */
+#define GO_TABLINE	'e'		/* may show tabline */
 #define GO_FORG		'f'		/* start GUI in foreground */
 #define GO_GREY		'g'		/* use grey menu items */
 #define GO_HORSCROLL	'h'		/* flexible horizontal scrolling */
@@ -238,7 +239,7 @@
 #define GO_TOOLBAR	'T'		/* add toolbar */
 #define GO_FOOTER	'F'		/* add footer */
 #define GO_VERTICAL	'v'		/* arrange dialog buttons vertically */
-#define GO_ALL		"aAbcfFghilmMprtTv" /* all possible flags for 'go' */
+#define GO_ALL		"aAbcefFghilmMprtTv" /* all possible flags for 'go' */
 
 /* flags for 'comments' option */
 #define COM_NEST	'n'		/* comments strings nest */
diff --git a/src/proto/gui.pro b/src/proto/gui.pro
index eacc2ac..93c4f5c 100644
--- a/src/proto/gui.pro
+++ b/src/proto/gui.pro
@@ -34,6 +34,9 @@
 int gui_xy2colrow __ARGS((int x, int y, int *colp));
 void gui_menu_cb __ARGS((vimmenu_T *menu));
 void gui_init_which_components __ARGS((char_u *oldval));
+int gui_use_tabline __ARGS((void));
+void gui_update_tabline __ARGS((void));
+void get_tabline_label __ARGS((tabpage_T *tp));
 void gui_remove_scrollbars __ARGS((void));
 void gui_create_scrollbar __ARGS((scrollbar_T *sb, int type, win_T *wp));
 scrollbar_T *gui_find_scrollbar __ARGS((long ident));
diff --git a/src/proto/gui_gtk_x11.pro b/src/proto/gui_gtk_x11.pro
index a97a1ac..30bde6a 100644
--- a/src/proto/gui_gtk_x11.pro
+++ b/src/proto/gui_gtk_x11.pro
@@ -5,6 +5,9 @@
 void gui_mch_stop_blink __ARGS((void));
 void gui_mch_start_blink __ARGS((void));
 int gui_mch_init_check __ARGS((void));
+void gui_mch_show_tabline __ARGS((int showit));
+void gui_mch_update_tabline __ARGS((void));
+void gui_mch_set_curtab __ARGS((int nr));
 int gui_mch_init __ARGS((void));
 void gui_mch_forked __ARGS((void));
 void gui_mch_new_colors __ARGS((void));
diff --git a/src/proto/screen.pro b/src/proto/screen.pro
index c2ce8d7..c534a1f 100644
--- a/src/proto/screen.pro
+++ b/src/proto/screen.pro
@@ -42,6 +42,7 @@
 int screen_del_lines __ARGS((int off, int row, int line_count, int end, int force, win_T *wp));
 int showmode __ARGS((void));
 void unshowmode __ARGS((int force));
+void get_trans_bufname __ARGS((buf_T *buf));
 int redrawing __ARGS((void));
 int messaging __ARGS((void));
 void showruler __ARGS((int always));
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 1c56ab1..629ced3 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -19,7 +19,9 @@
 int make_tabpages __ARGS((int maxcount));
 int valid_tabpage __ARGS((tabpage_T *tpc));
 tabpage_T *find_tabpage __ARGS((int n));
+int tabpage_index __ARGS((tabpage_T *ftp));
 void goto_tabpage __ARGS((int n));
+void goto_tabpage_tp __ARGS((tabpage_T *tp));
 void tabpage_move __ARGS((int nr));
 void win_goto __ARGS((win_T *wp));
 win_T *win_find_nr __ARGS((int winnr));
@@ -42,7 +44,7 @@
 void win_comp_scroll __ARGS((win_T *wp));
 void command_height __ARGS((long old_p_ch));
 void last_status __ARGS((int morewin));
-int tabpageline_height __ARGS((void));
+int tabline_height __ARGS((void));
 char_u *grab_file_name __ARGS((long count, linenr_T *file_lnum));
 char_u *file_name_at_cursor __ARGS((int options, long count, linenr_T *file_lnum));
 char_u *file_name_in_line __ARGS((char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum));
diff --git a/src/regexp.c b/src/regexp.c
index 69acb69..48bad94 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -3861,8 +3861,16 @@
 		}
 		else
 		{
-		    top = curbuf->b_visual_start;
-		    bot = curbuf->b_visual_end;
+		    if (lt(curbuf->b_visual_start, curbuf->b_visual_end))
+		    {
+			top = curbuf->b_visual_start;
+			bot = curbuf->b_visual_end;
+		    }
+		    else
+		    {
+			top = curbuf->b_visual_end;
+			bot = curbuf->b_visual_start;
+		    }
 		    mode = curbuf->b_visual_mode;
 		}
 		lnum = reglnum + reg_firstlnum;
@@ -5092,8 +5100,8 @@
 			/* Tried first position already, advance. */
 			if (rp->rs_state == RS_STAR_LONG)
 			{
-			    /* Trying for longest matc, but couldn't or didn't
-			     * match -- back up one char. */
+			    /* Trying for longest match, but couldn't or
+			     * didn't match -- back up one char. */
 			    if (--rst->count < rst->minval)
 				break;
 			    if (reginput == regline)
@@ -5149,8 +5157,8 @@
 	    break;
 	}
 
-	/* If we want to continue the inner loop or didn't pop a state contine
-	 * matching loop */
+	/* If we want to continue the inner loop or didn't pop a state
+	 * continue matching loop */
 	if (status == RA_CONT || rp == (regitem_T *)
 			     ((char *)regstack.ga_data + regstack.ga_len) - 1)
 	    break;
diff --git a/src/screen.c b/src/screen.c
index 07cf991..692318c 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -5344,12 +5344,7 @@
     {
 	fillchar = fillchar_status(&attr, wp == curwin);
 
-	if (buf_spname(wp->w_buffer) != NULL)
-	    STRCPY(NameBuff, buf_spname(wp->w_buffer));
-	else
-	    home_replace(wp->w_buffer, wp->w_buffer->b_fname, NameBuff,
-							      MAXPATHL, TRUE);
-	trans_characters(NameBuff, MAXPATHL);
+	get_trans_bufname(wp->w_buffer);
 	p = NameBuff;
 	len = (int)STRLEN(p);
 
@@ -6170,14 +6165,24 @@
 	    matchcol = 0;
 	else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL
 		|| (shl->rm.endpos[0].lnum == 0
-		    && shl->rm.endpos[0].col == shl->rm.startpos[0].col))
+		    && shl->rm.endpos[0].col <= shl->rm.startpos[0].col))
 	{
-	    matchcol = shl->rm.startpos[0].col + 1;
-	    if (ml_get_buf(shl->buf, lnum, FALSE)[matchcol - 1] == NUL)
+	    char_u	*ml = ml_get_buf(shl->buf, lnum, FALSE);
+
+	    matchcol = shl->rm.startpos[0].col;
+	    ml += matchcol;
+	    if (*ml == NUL)
 	    {
+		++matchcol;
 		shl->lnum = 0;
 		break;
 	    }
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
+		matchcol += mb_ptr2len(ml);
+	    else
+#endif
+		++matchcol;
 	}
 	else
 	    matchcol = shl->rm.endpos[0].col;
@@ -8577,7 +8582,16 @@
 
     redraw_tabline = FALSE;
 
-    if (tabpageline_height() < 1)
+#ifdef FEAT_GUI_TABLINE
+    /* When the GUI has the tabline then this always returns zero. */
+    if (gui_use_tabline())
+    {
+	gui_update_tabline();
+	return;
+    }
+#endif
+
+    if (tabline_height() < 1)
 	return;
 
 #if defined(FEAT_STL_OPT)
@@ -8670,12 +8684,8 @@
 	    room = scol - col + tabwidth - 1;
 	    if (room > 0)
 	    {
-		if (buf_spname(cwp->w_buffer) != NULL)
-		    STRCPY(NameBuff, buf_spname(cwp->w_buffer));
-		else
-		    home_replace(cwp->w_buffer, cwp->w_buffer->b_fname, NameBuff,
-								  MAXPATHL, TRUE);
-		trans_characters(NameBuff, MAXPATHL);
+		/* Get buffer name in NameBuff[] */
+		get_trans_bufname(cwp->w_buffer);
 		len = vim_strsize(NameBuff);
 		p = NameBuff;
 #ifdef FEAT_MBYTE
@@ -8719,6 +8729,21 @@
 	}
     }
 }
+
+/*
+ * Get buffer name for "buf" into NameBuff[].
+ * Takes care of special buffer names and translates special characters.
+ */
+    void
+get_trans_bufname(buf)
+    buf_T	*buf;
+{
+    if (buf_spname(buf) != NULL)
+	STRCPY(NameBuff, buf_spname(buf));
+    else
+	home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
+    trans_characters(NameBuff, MAXPATHL);
+}
 #endif
 
 #if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT)
diff --git a/src/search.c b/src/search.c
index c0be23b..e92985a 100644
--- a/src/search.c
+++ b/src/search.c
@@ -602,7 +602,11 @@
 # ifdef FEAT_EVAL
 		    submatch = first_submatch(&regmatch);
 # endif
-		    ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
+		    /* Line me be past end of buffer for "\n\zs". */
+		    if (lnum + matchpos.lnum > buf->b_ml.ml_line_count)
+			ptr = (char_u *)"";
+		    else
+			ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
 
 		    /*
 		     * Forward search in the first line: match should be after
@@ -886,6 +890,15 @@
 	return FAIL;
     }
 
+    /* A pattern like "\n\zs" may go past the last line. */
+    if (pos->lnum > buf->b_ml.ml_line_count)
+    {
+	pos->lnum = buf->b_ml.ml_line_count;
+	pos->col = STRLEN(ml_get_buf(buf, pos->lnum, FALSE));
+	if (pos->col > 0)
+	    --pos->col;
+    }
+
     return submatch + 1;
 }
 
diff --git a/src/structs.h b/src/structs.h
index bb02a75..adbbdc0 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -782,8 +782,9 @@
 	} term;
 	struct
 	{
-	    char_u	    fg_color;	/* foreground color number */
-	    char_u	    bg_color;	/* background color number */
+	    /* These colors need to be > 8 bits to hold 256. */
+	    short_u	    fg_color;	/* foreground color number */
+	    short_u	    bg_color;	/* background color number */
 	} cterm;
 # ifdef FEAT_GUI
 	struct
diff --git a/src/tag.c b/src/tag.c
index 8cef850..5f01115 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -509,6 +509,13 @@
 		tagmatchname = vim_strsave(name);
 	    }
 
+	    /*
+	     * If a count is supplied to the ":tag <name>" command, then
+	     * jump to count'th matching tag.
+	     */
+	    if (type == DT_TAG && count > 0)
+		cur_match = count - 1;
+
 	    if (type == DT_SELECT || type == DT_JUMP)
 		cur_match = MAXCOL - 1;
 	    max_num_matches = cur_match + 1;
diff --git a/src/term.c b/src/term.c
index 621d35b..596de51 100644
--- a/src/term.c
+++ b/src/term.c
@@ -4766,6 +4766,9 @@
 	 * four bytes which are to be taken as a pointer to the vimmenu_T
 	 * structure.
 	 *
+	 * A tab line event is encodded as K_SPECIAL KS_TABLINE nr, where "nr"
+	 * is one byte with the tab index.
+	 *
 	 * A scrollbar event is K_SPECIAL, KS_VER_SCROLLBAR, KE_FILLER followed
 	 * by one byte representing the scrollbar number, and then four bytes
 	 * representing a long_u which is the new value of the scrollbar.
@@ -4786,6 +4789,16 @@
 	    slen += num_bytes;
 	}
 # endif
+# ifdef FEAT_GUI_TABLINE
+	else if (key_name[0] == (int)KS_TABLINE)
+	{
+	    num_bytes = get_bytes_from_buf(tp + slen, bytes, 1);
+	    if (num_bytes == -1)
+		return -1;
+	    current_tab = (int)bytes[0];
+	    slen += num_bytes;
+	}
+# endif
 # ifndef USE_ON_FLY_SCROLL
 	else if (key_name[0] == (int)KS_VER_SCROLLBAR)
 	{
diff --git a/src/version.h b/src/version.h
index 9838f1b..1cffc09 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 23)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 23, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 24)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 24, compiled "
diff --git a/src/window.c b/src/window.c
index c116dfc..f0a4265 100644
--- a/src/window.c
+++ b/src/window.c
@@ -86,7 +86,7 @@
 #ifdef FEAT_WINDOWS
 static long p_ch_used = 1L;		/* value of 'cmdheight' when frame
 					   size was set */
-# define ROWS_AVAIL (Rows - p_ch - tabpageline_height())
+# define ROWS_AVAIL (Rows - p_ch - tabline_height())
 #else
 # define ROWS_AVAIL (Rows - p_ch)
 #endif
@@ -908,7 +908,7 @@
 	if (flags & (WSP_TOP | WSP_BOT))
 	{
 	    /* set height and row of new window to full height */
-	    wp->w_winrow = tabpageline_height();
+	    wp->w_winrow = tabline_height();
 	    wp->w_height = curfrp->fr_height - (p_ls > 0);
 	    wp->w_status_height = (p_ls > 0);
 	}
@@ -1543,7 +1543,7 @@
 	dir = 'b';
 #endif
     win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
-		      topframe, dir, 0, tabpageline_height(),
+		      topframe, dir, 0, tabline_height(),
 					   (int)Columns, topframe->fr_height);
 }
 
@@ -1830,7 +1830,7 @@
 {
     win_T	*wp;
     tabpage_T   *tp, *nexttp;
-    int		h = tabpageline_height();
+    int		h = tabline_height();
 
     ++RedrawingDisabled;
 
@@ -1866,7 +1866,7 @@
 
     --RedrawingDisabled;
 
-    if (h != tabpageline_height())
+    if (h != tabline_height())
 	shell_new_rows();
 }
 
@@ -3041,7 +3041,7 @@
 	    tp->tp_next = newtp;
 	}
 	win_init_size();
-	firstwin->w_winrow = tabpageline_height();
+	firstwin->w_winrow = tabline_height();
 
 	newtp->tp_topframe = topframe;
 	last_status(FALSE);
@@ -3142,6 +3142,22 @@
 }
 
 /*
+ * Get index of tab page "tp".  First one has index 1.
+ * When not found returns number of tab pages.
+ */
+    int
+tabpage_index(ftp)
+    tabpage_T	*ftp;
+{
+    int		i = 1;
+    tabpage_T	*tp;
+
+    for (tp = first_tabpage; tp != NULL && tp != ftp; tp = tp->tp_next)
+	++i;
+    return i;
+}
+
+/*
  * Prepare for leaving the current tab page.
  * When autocomands change "curtab" we don't leave the tab page and return
  * FAIL.
@@ -3223,7 +3239,11 @@
     /* The tabpage line may have appeared or disappeared, may need to resize
      * the frames for that.  When the Vim window was resized need to update
      * frame sizes too. */
-    if (curtab->tp_old_Rows != Rows || old_off != firstwin->w_winrow)
+    if (curtab->tp_old_Rows != Rows || (old_off != firstwin->w_winrow
+#ifdef FEAT_GUI_TABLINE
+			    && !gui_use_tabline()
+#endif
+		))
 	shell_new_rows();
 #ifdef FEAT_VERTSPLIT
     if (curtab->tp_old_Columns != Columns && starting == 0)
@@ -3233,12 +3253,8 @@
 #if defined(FEAT_GUI)
     /* When 'guioptions' includes 'L' or 'R' may have to remove or add
      * scrollbars.  Have to update them anyway. */
-    if (gui.in_use)
-    {
-	out_flush();
-	gui_init_which_components(NULL);
+    if (gui.in_use && starting == 0)
 	gui_update_scrollbars(TRUE);
-    }
     need_mouse_correct = TRUE;
 #endif
 
@@ -3247,6 +3263,7 @@
 
 /*
  * Go to tab page "n".  For ":tab N" and "Ngt".
+ * When "n" is 9999 go to the last tab page.
  */
     void
 goto_tabpage(n)
@@ -3285,12 +3302,16 @@
 	    ttp = tp;
 	}
     }
+    else if (n == 9999)
+    {
+	/* Go to last tab page. */
+	for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next)
+	    ;
+    }
     else
     {
 	/* Go to tab page "n". */
-	i = 0;
-	for (tp = first_tabpage; ++i != n && tp != NULL; tp = tp->tp_next)
-	    ;
+	tp = find_tabpage(n);
 	if (tp == NULL)
 	{
 	    beep_flush();
@@ -3298,6 +3319,22 @@
 	}
     }
 
+    goto_tabpage_tp(tp);
+
+#ifdef FEAT_GUI_TABLINE
+    if (gui_use_tabline())
+	gui_mch_set_curtab(tabpage_index(tp));
+#endif
+}
+
+/*
+ * Go to tabpage "tp".
+ * Note: doesn't update the GUI tab.
+ */
+    void
+goto_tabpage_tp(tp)
+    tabpage_T	*tp;
+{
     if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer) == OK)
     {
 	if (valid_tabpage(tp))
@@ -4071,7 +4108,7 @@
     int
 win_comp_pos()
 {
-    int		row = tabpageline_height();
+    int		row = tabline_height();
     int		col = 0;
 
     frame_comp_pos(topframe, &row, &col);
@@ -5169,8 +5206,13 @@
  * Return the number of lines used by the tab page line.
  */
     int
-tabpageline_height()
+tabline_height()
 {
+#ifdef FEAT_GUI_TABLINE
+    /* When the GUI has the tabline then this always returns zero. */
+    if (gui_use_tabline())
+	return 0;
+#endif
     switch (p_stal)
     {
 	case 0: return 0;
@@ -5516,7 +5558,7 @@
 	if (total < n)
 	    total = n;
     }
-    total += tabpageline_height();
+    total += tabline_height();
 #else
     total = 1;		/* at least one window should have a line! */
 #endif