summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2006-02-24 23:53:04 +0000
committerBram Moolenaar <Bram@vim.org>2006-02-24 23:53:04 +0000
commit32466aa2e9c45ab355dbaf99a9eedf334bc2e29f (patch)
tree1644d959a04f9f8c6ea5a8fe3c79f037c6915559 /src
parent2a3f7eeebfa05a33cc1d8fbba66a3dff976e8dd7 (diff)
updated for version 7.0206v7.0206
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 1cdfd742d4..8ff3e3b2e6 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 05897e2316..41245b5786 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 913d3e9a40..382d1af165 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 fef09d02f7..52525e6c47 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 71a0e2afb6..393f714944 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 416fd3e350..0d7188ac1a 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 df6273ffca..74998d93ba 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 efe7915675..e2d90132f1 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 d46b10c3c1..1263e81838 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 3a1b31cdd1..9b97ffd2fc 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 c706302d4b..f1a9e64046 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 c608f9d4ad..4cae9a1738 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;