summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile4
-rwxr-xr-xsrc/auto/configure6
-rw-r--r--src/configure.in9
-rw-r--r--src/eval.c41
-rw-r--r--src/ex_cmds.h12
-rw-r--r--src/ex_cmds2.c25
-rw-r--r--src/ex_docmd.c47
-rw-r--r--src/feature.h7
-rw-r--r--src/globals.h4
-rw-r--r--src/gui.c104
-rw-r--r--src/gui.h1
-rw-r--r--src/gui_gtk_x11.c413
-rw-r--r--src/keymap.h5
-rw-r--r--src/main.c12
-rw-r--r--src/normal.c24
-rw-r--r--src/option.c4
-rw-r--r--src/option.h3
-rw-r--r--src/proto/gui.pro3
-rw-r--r--src/proto/gui_gtk_x11.pro3
-rw-r--r--src/proto/screen.pro1
-rw-r--r--src/proto/window.pro4
-rw-r--r--src/regexp.c20
-rw-r--r--src/screen.c57
-rw-r--r--src/search.c15
-rw-r--r--src/structs.h5
-rw-r--r--src/tag.c7
-rw-r--r--src/term.c13
-rw-r--r--src/version.h4
-rw-r--r--src/window.c78
29 files changed, 699 insertions, 232 deletions
diff --git a/src/Makefile b/src/Makefile
index 1cdfd742d..8ff3e3b2e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -548,8 +548,8 @@ LINT_OPTIONS = -beprxzF
#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 05897e231..41245b578 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -2780,7 +2780,7 @@ if test -z "$CFLAGS"; then
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 @@ echo "${ECHO_T}yes, Darwin support excluded" >&6
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 "$as_me:$LINENO: checking for GCC 3 or later" >&5
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 913d3e9a4..382d1af16 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -29,7 +29,7 @@ if test -z "$CFLAGS"; then
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 @@ if test "`(uname) 2>/dev/null`" = Darwin; then
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 @@ fi
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 fef09d02f..52525e6c4 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -14934,7 +14934,6 @@ f_tabpagenr(argvars, rettv)
{
int nr = 1;
#ifdef FEAT_WINDOWS
- tabpage_T *tp;
char_u *arg;
if (argvars[0].v_type != VAR_UNKNOWN)
@@ -14944,15 +14943,13 @@ f_tabpagenr(argvars, rettv)
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 @@ f_writefile(argvars, rettv)
/*
* Translate a String variable into a position.
+ * Returns NULL when there is an error.
*/
static pos_T *
var2fpos(varp, lnum)
@@ -15626,6 +15624,39 @@ var2fpos(varp, lnum)
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 71a0e2afb..393f71494 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -881,22 +881,30 @@ EX(CMD_tab, "tab", ex_wrongmodifier,
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 416fd3e35..0d7188ac1 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -2155,7 +2155,7 @@ ex_argdelete(eap)
}
/*
- * ":argdo", ":windo", ":bufdo"
+ * ":argdo", ":windo", ":bufdo", ":tabdo"
*/
void
ex_listdo(eap)
@@ -2163,7 +2163,8 @@ ex_listdo(eap)
{
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 @@ ex_listdo(eap)
#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 @@ ex_listdo(eap)
#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(wp);
+ wp = curwin->w_next;
+ }
+ else if (eap->cmdidx == CMD_tabdo)
+ {
+ /* go to window "tp" */
+ if (!valid_tabpage(tp))
break;
- win_goto(win);
- win = curwin->w_next;
+ 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 df6273ffc..74998d93b 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -156,7 +156,6 @@ 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
@@ -167,7 +166,6 @@ static void ex_tabs __ARGS((exarg_T *eap));
# 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 @@ do_one_cmd(cmdlinep, sourcing,
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 @@ ex_tabclose(eap)
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 @@ ex_tabclose(eap)
tabpage_close(eap->forceit);
}
- if (h != tabpageline_height())
+ if (h != tabline_height())
shell_new_rows();
}
@@ -6284,7 +6275,7 @@ ex_tabonly(eap)
{
tabpage_T *tp;
int done;
- int h = tabpageline_height();
+ int h = tabline_height();
# ifdef FEAT_CMDWIN
if (cmdwin_type != 0)
@@ -6314,7 +6305,7 @@ ex_tabonly(eap)
}
}
- if (h != tabpageline_height())
+ if (h != tabline_height())
shell_new_rows();
}
@@ -7042,17 +7033,23 @@ tabpage_new()
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 efe791567..e2d90132f 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 d46b10c3c..1263e8183 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -435,6 +435,10 @@ EXTERN vimmenu_T *current_menu;
/* 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 3a1b31cdd..9b97ffd2f 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -26,6 +26,9 @@ static int gui_screenstr __ARGS((int off, int len, int flags, guicolor_T fg, gui
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 @@ gui_set_shellsize(mustset, fit_to_display)
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 @@ static int prev_which_scrollbars[3] = {-1, -1, -1};
/*
* 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 @@ gui_init_which_components(oldval)
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 @@ gui_init_which_components(oldval)
/* 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 @@ gui_init_which_components(oldval)
}
}
+#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 c706302d4..f1a9e6404 100644
--- a/src/gui.h
+++ b/src/gui.h
@@ -393,6 +393,7 @@ typedef struct Gui
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 c608f9d4a..4cae9a173 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -2827,6 +2827,145 @@ delete_event_cb(GtkWidget *widget, GdkEventAny *event, gpointer data)
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 @@ set_toolbar_style(GtkToolbar *toolbar)
#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_mch_init(void)
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 @@ gui_mch_init(void)
}
#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 @@ gui_mch_new_colors(void)
}
}
-#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 0aa447498..3ffea9319 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 @@ enum key_extra
#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 705acf5ef..413ca1f5c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -880,6 +880,18 @@ main
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 4f4ffa954..cc9d0d165 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -74,6 +74,9 @@ static void nv_zet __ARGS((cmdarg_T *cap));
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 @@ static const struct nv_cmd
{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 @@ nv_hor_scrollbar(cap)
}
#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 @@ nv_ident(cap)
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 192500010..d32cf5e9d 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1099,9 +1099,9 @@ static struct vimoption
#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 ebf154b5a..54ae88949 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 eacc2ac82..93c4f5cc3 100644
--- a/src/proto/gui.pro
+++ b/src/proto/gui.pro
@@ -34,6 +34,9 @@ void gui_send_mouse_event __ARGS((int button, int x, int y, int repeated_click,
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 a97a1ac85..30bde6a13 100644
--- a/src/proto/gui_gtk_x11.pro
+++ b/src/proto/gui_gtk_x11.pro
@@ -5,6 +5,9 @@ void gui_mch_set_blinking __ARGS((long waittime, long on, long off));
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 c2ce8d74c..c534a1f9e 100644
--- a/src/proto/screen.pro
+++ b/src/proto/screen.pro
@@ -42,6 +42,7 @@ int screen_ins_lines __ARGS((int off, int row, int line_count, int end, win_T *w
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 1c56ab1c1..629ced385 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -19,7 +19,9 @@ int may_open_tabpage __ARGS((void));
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_drag_vsep_line __ARGS((win_T *dragwin, int offset));
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 69acb6987..48bad944f 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -3861,8 +3861,16 @@ regmatch(scan)
}
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 @@ regmatch(scan)
/* 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 @@ regmatch(scan)
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 07cf99145..692318c29 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -5344,12 +5344,7 @@ win_redr_status(wp)
{
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 @@ next_search_hl(win, shl, lnum, mincol)
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 @@ draw_tabline()
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 @@ draw_tabline()
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 @@ draw_tabline()
}
}
}
+
+/*
+ * 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 c0be23ba7..e92985a8c 100644
--- a/src/search.c
+++ b/src/search.c
@@ -602,7 +602,11 @@ searchit(win, buf, pos, dir, pat, count, options, pat_use)
# 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 @@ searchit(win, buf, pos, dir, pat, count, options, pat_use)
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 bb02a75ea..adbbdc07e 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -782,8 +782,9 @@ typedef struct attr_entry
} 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 8cef850d2..5f01115cb 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -509,6 +509,13 @@ do_tag(tag, type, count, forceit, verbose)
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 621d35ba2..596de514a 100644
--- a/src/term.c
+++ b/src/term.c
@@ -4766,6 +4766,9 @@ check_termcode(max_offset, buf, buflen)
* 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 @@ check_termcode(max_offset, buf, buflen)
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 9838f1b90..1cffc094a 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 c116dfc84..f0a4265b0 100644
--- a/src/window.c
+++ b/src/window.c
@@ -86,7 +86,7 @@ static void win_new_height __ARGS((win_T *, int));
#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 @@ win_split_ins(size, flags, newwin, dir)
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 @@ win_equal(next_curwin, current, dir)
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 @@ close_windows(buf, keep_curwin)
{
win_T *wp;
tabpage_T *tp, *nexttp;
- int h = tabpageline_height();
+ int h = tabline_height();
++RedrawingDisabled;
@@ -1866,7 +1866,7 @@ close_windows(buf, keep_curwin)
--RedrawingDisabled;
- if (h != tabpageline_height())
+ if (h != tabline_height())
shell_new_rows();
}
@@ -3041,7 +3041,7 @@ win_new_tabpage(after)
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 @@ find_tabpage(n)
}
/*
+ * 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 @@ enter_tabpage(tp, old_curbuf)
/* 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 @@ enter_tabpage(tp, old_curbuf)
#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 @@ enter_tabpage(tp, old_curbuf)
/*
* 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 @@ goto_tabpage(n)
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(n)
}
}
+ 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 @@ win_size_restore(gap)
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 @@ last_status_rec(fr, statusline)
* 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 @@ min_rows()
if (total < n)
total = n;
}
- total += tabpageline_height();
+ total += tabline_height();
#else
total = 1; /* at least one window should have a line! */
#endif