summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2006-02-16 22:11:02 +0000
committerBram Moolenaar <Bram@vim.org>2006-02-16 22:11:02 +0000
commitf740b29ae2a346e44c34001b3bf8ecfa0c7857bd (patch)
tree5b62807af1359d3df97367448927cdbb53969448 /src
parent4c7ed462cb7813730b4f15f9cb09f1b26d097fca (diff)
downloadvim-git-f740b29ae2a346e44c34001b3bf8ecfa0c7857bd.tar.gz
updated for version 7.0199v7.0199
Diffstat (limited to 'src')
-rwxr-xr-xsrc/auto/configure2
-rw-r--r--src/buffer.c29
-rw-r--r--src/configure.in2
-rw-r--r--src/diff.c1
-rw-r--r--src/eval.c2
-rw-r--r--src/ex_cmds2.c3
-rw-r--r--src/ex_docmd.c97
-rw-r--r--src/globals.h10
-rw-r--r--src/if_mzsch.c7
-rw-r--r--src/if_python.c4
-rw-r--r--src/if_ruby.c2
-rw-r--r--src/main.c28
-rw-r--r--src/mark.c3
-rw-r--r--src/misc1.c2
-rw-r--r--src/misc2.c2
-rw-r--r--src/normal.c31
-rw-r--r--src/option.c84
-rw-r--r--src/proto/ex_docmd.pro2
-rw-r--r--src/proto/window.pro5
-rw-r--r--src/screen.c95
-rw-r--r--src/structs.h1
-rw-r--r--src/version.h4
-rw-r--r--src/window.c249
23 files changed, 503 insertions, 162 deletions
diff --git a/src/auto/configure b/src/auto/configure
index 794fd8f42..05897e231 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -15088,7 +15088,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'`
- if test "$gccmajor" > "2"; then
+ if test "$gccmajor" -gt "2"; then
DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
fi
fi
diff --git a/src/buffer.c b/src/buffer.c
index eb8799c58..28ed6b985 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1062,21 +1062,7 @@ do_buffer(action, start, dir, count, forceit)
/* Close any other windows on this buffer, then make it empty. */
#ifdef FEAT_WINDOWS
- {
- win_T *wp, *nextwp;
-
- for (wp = firstwin; wp != NULL; wp = nextwp)
- {
- nextwp = wp->w_next;
- if (wp != curwin && wp->w_buffer == buf)
- {
- /* Start all over, autocommands may change the window
- * layout. */
- nextwp = firstwin;
- win_close(wp, FALSE);
- }
- }
- }
+ close_windows(buf, TRUE);
#endif
setpcmark();
retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
@@ -1095,9 +1081,11 @@ do_buffer(action, start, dir, count, forceit)
#ifdef FEAT_WINDOWS
/*
* If the deleted buffer is the current one, close the current window
- * (unless it's the only window).
+ * (unless it's the only window). Repeat this so long as we end up in
+ * a window with this buffer.
*/
- while (buf == curbuf && firstwin != lastwin)
+ while (buf == curbuf
+ && (firstwin != lastwin || first_tabpage->tp_next != NULL))
win_close(curwin, FALSE);
#endif
@@ -1107,7 +1095,7 @@ do_buffer(action, start, dir, count, forceit)
if (buf != curbuf)
{
#ifdef FEAT_WINDOWS
- close_windows(buf);
+ close_windows(buf, FALSE);
#endif
if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
close_buffer(NULL, buf, action);
@@ -1317,7 +1305,7 @@ set_curbuf(buf, action)
{
#ifdef FEAT_WINDOWS
if (unload)
- close_windows(prevbuf);
+ close_windows(prevbuf, FALSE);
#endif
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
if (buf_valid(prevbuf) && !aborting())
@@ -4707,6 +4695,7 @@ write_viminfo_bufferlist(fp)
buf_T *buf;
#ifdef FEAT_WINDOWS
win_T *win;
+ tabpage_T *tp;
#endif
char_u *line;
int max_buffers;
@@ -4723,7 +4712,7 @@ write_viminfo_bufferlist(fp)
return;
#ifdef FEAT_WINDOWS
- for (win = firstwin; win != NULL; win = win->w_next)
+ FOR_ALL_TAB_WINDOWS(tp, win)
set_last_cursor(win);
#else
set_last_cursor(curwin);
diff --git a/src/configure.in b/src/configure.in
index 04001de21..4324101b8 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -2761,7 +2761,7 @@ 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'`
- if test "$gccmajor" > "2"; then
+ if test "$gccmajor" -gt "2"; then
DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'"
fi
fi
diff --git a/src/diff.c b/src/diff.c
index 22e18f316..7c5bbd343 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1075,6 +1075,7 @@ diff_win_options(wp, addbuf)
/*
* Set options not to show diffs. For the current window or all windows.
+ * Only in the current tab page.
*/
void
ex_diffoff(eap)
diff --git a/src/eval.c b/src/eval.c
index 6ec0975d7..d29f1a4f1 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -15509,11 +15509,13 @@ var2fpos(varp, lnum)
pos.col = 0;
if (name[1] == '0') /* "w0": first visible line */
{
+ update_topline();
pos.lnum = curwin->w_topline;
return &pos;
}
else if (name[1] == '$') /* "w$": last visible line */
{
+ validate_botline();
pos.lnum = curwin->w_botline - 1;
return &pos;
}
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 8a7999ff2..0e671c8af 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1761,8 +1761,9 @@ alist_check_arg_idx()
{
#ifdef FEAT_WINDOWS
win_T *win;
+ tabpage_T *tp;
- for (win = firstwin; win != NULL; win = win->w_next)
+ FOR_ALL_TAB_WINDOWS(tp, win)
if (win->w_alist == curwin->w_alist)
check_arg_idx(win);
#else
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index e87bb6f6f..195f19d7c 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -148,7 +148,7 @@ static void ex_cquit __ARGS((exarg_T *eap));
static void ex_quit_all __ARGS((exarg_T *eap));
#ifdef FEAT_WINDOWS
static void ex_close __ARGS((exarg_T *eap));
-static void ex_win_close __ARGS((int forceit, win_T *win));
+static void ex_win_close __ARGS((int forceit, win_T *win, tabpage_T *tp));
static void ex_only __ARGS((exarg_T *eap));
static void ex_all __ARGS((exarg_T *eap));
static void ex_resize __ARGS((exarg_T *eap));
@@ -6144,7 +6144,7 @@ ex_close(eap)
else
# endif
if (!text_locked())
- ex_win_close(eap->forceit, curwin);
+ ex_win_close(eap->forceit, curwin, NULL);
}
#ifdef FEAT_QUICKFIX
@@ -6160,16 +6160,21 @@ ex_pclose(eap)
for (win = firstwin; win != NULL; win = win->w_next)
if (win->w_p_pvw)
{
- ex_win_close(eap->forceit, win);
+ ex_win_close(eap->forceit, win, NULL);
break;
}
}
#endif
+/*
+ * Close window "win" and take care of handling closing the last window for a
+ * modified buffer.
+ */
static void
-ex_win_close(forceit, win)
+ex_win_close(forceit, win, tp)
int forceit;
win_T *win;
+ tabpage_T *tp; /* NULL or the tab page "win" is in */
{
int need_hide;
buf_T *buf = win->w_buffer;
@@ -6196,39 +6201,93 @@ ex_win_close(forceit, win)
#ifdef FEAT_GUI
need_mouse_correct = TRUE;
#endif
+
/* free buffer when not hiding it or when it's a scratch buffer */
- win_close(win, !need_hide && !P_HID(buf));
+ if (tp == NULL)
+ win_close(win, !need_hide && !P_HID(buf));
+ else
+ win_close_othertab(win, !need_hide && !P_HID(buf), tp);
}
/*
- * ":tabclose": close current tab page, unless it is the last one
+ * ":tabclose": close current tab page, unless it is the last one.
+ * ":tabclose N": close tab page N.
*/
static void
ex_tabclose(eap)
exarg_T *eap;
{
+ tabpage_T *tp;
+
# ifdef FEAT_CMDWIN
if (cmdwin_type != 0)
cmdwin_result = K_IGNORE;
else
# endif
- if (!text_locked())
+ if (first_tabpage->tp_next == NULL)
+ EMSG(_("E999: Cannot close last tab page"));
+ else
{
- if (first_tabpage->tp_next == NULL)
- EMSG(_("E999: Cannot close last tab page"));
- else
+ if (eap->addr_count > 0)
{
- /* First close all the windows but the current one. If that
- * worked then close the last window in this tab, that will
- * close it. */
- ex_only(eap);
- if (lastwin == firstwin)
- ex_win_close(eap->forceit, curwin);
+ tp = find_tabpage((int)eap->line2);
+ if (tp == NULL)
+ {
+ beep_flush();
+ return;
+ }
+ if (tp->tp_topframe != topframe)
+ {
+ tabpage_close_other(tp, eap->forceit);
+ return;
+ }
}
+ if (!text_locked())
+ tabpage_close(eap->forceit);
}
}
/*
+ * Close the current tab page.
+ */
+ void
+tabpage_close(forceit)
+ int forceit;
+{
+ /* First close all the windows but the current one. If that worked then
+ * close the last window in this tab, that will close it. */
+ close_others(TRUE, forceit);
+ if (lastwin == firstwin)
+ ex_win_close(forceit, curwin, NULL);
+# ifdef FEAT_GUI
+ need_mouse_correct = TRUE;
+# endif
+}
+
+/*
+ * Close tab page "tp", which is not the current tab page.
+ * Note that autocommands may make "tp" invalid.
+ */
+ void
+tabpage_close_other(tp, forceit)
+ tabpage_T *tp;
+ int forceit;
+{
+ int done = 0;
+
+ /* Limit to 1000 windows, autocommands may add a window while we close
+ * one. OK, so I'm paranoid... */
+ while (++done < 1000)
+ {
+ ex_win_close(forceit, tp->tp_firstwin, tp);
+
+ /* Autocommands may delete the tab page under our fingers. */
+ if (!valid_tabpage(tp))
+ break;
+ }
+}
+
+/*
* ":only".
*/
static void
@@ -6689,13 +6748,14 @@ alist_slash_adjust()
int i;
# ifdef FEAT_WINDOWS
win_T *wp;
+ tabpage_T *tp;
# endif
for (i = 0; i < GARGCOUNT; ++i)
if (GARGLIST[i].ae_fname != NULL)
slash_adjust(GARGLIST[i].ae_fname);
# ifdef FEAT_WINDOWS
- for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ FOR_ALL_TAB_WINDOWS(tp, wp)
if (wp->w_alist != &global_alist)
for (i = 0; i < WARGCOUNT(wp); ++i)
if (WARGLIST(wp)[i].ae_fname != NULL)
@@ -6925,7 +6985,8 @@ ex_tabedit(eap)
# ifdef FEAT_SCROLLBIND
curwin->w_p_scb = FALSE;
# endif
- do_exedit(eap, NULL);
+ if (*eap->arg != NUL)
+ do_exedit(eap, NULL);
}
# ifdef FEAT_BROWSE
diff --git a/src/globals.h b/src/globals.h
index 57d7d0922..c6409b96b 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -42,7 +42,7 @@ EXTERN long Columns INIT(= 80); /* nr of columns in the screen */
EXTERN schar_T *ScreenLines INIT(= NULL);
EXTERN sattr_T *ScreenAttrs INIT(= NULL);
EXTERN unsigned *LineOffset INIT(= NULL);
-EXTERN char_u *LineWraps INIT(= NULL);
+EXTERN char_u *LineWraps INIT(= NULL); /* line wraps to next line */
#ifdef FEAT_MBYTE
/*
@@ -61,6 +61,10 @@ EXTERN u8char_T *ScreenLinesC2 INIT(= NULL); /* second composing char */
EXTERN schar_T *ScreenLines2 INIT(= NULL);
#endif
+#ifdef FEAT_WINDOWS
+EXTERN char_u *TabPageIdxs INIT(= NULL); /* indexes for tab page line */
+#endif
+
EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
@@ -482,6 +486,10 @@ EXTERN win_T *lastwin; /* last window */
EXTERN win_T *prevwin INIT(= NULL); /* previous window */
# define W_NEXT(wp) ((wp)->w_next)
# define FOR_ALL_WINDOWS(wp) for (wp = firstwin; wp != NULL; wp = wp->w_next)
+#define FOR_ALL_TAB_WINDOWS(tp, wp) \
+ for ((tp) = first_tabpage; (tp) != NULL; (tp) = (tp)->tp_next) \
+ for ((wp) = ((tp)->tp_topframe == topframe) \
+ ? firstwin : (tp)->tp_firstwin; (wp); (wp) = (wp)->w_next)
#else
# define firstwin curwin
# define lastwin curwin
diff --git a/src/if_mzsch.c b/src/if_mzsch.c
index 4d5bb3223..9eb524a6a 100644
--- a/src/if_mzsch.c
+++ b/src/if_mzsch.c
@@ -1423,7 +1423,8 @@ get_window_count(void *data, int argc, Scheme_Object **argv)
win_T *w;
int n = 0;
- for (w = firstwin; w; w = w->w_next) ++n;
+ for (w = firstwin; w != NULL; w = w->w_next)
+ ++n;
return scheme_make_integer(n);
}
@@ -1439,7 +1440,7 @@ get_window_list(void *data, int argc, Scheme_Object **argv)
buf = get_buffer_arg(prim->name, 0, argc, argv);
list = scheme_null;
- for (w = firstwin; w; w = w->w_next)
+ for (w = firstwin; w != NULL; w = w->w_next)
if (w->w_buffer == buf->buf)
list = scheme_make_pair(window_new(w), list);
@@ -1500,7 +1501,7 @@ get_window_by_num(void *data, int argc, Scheme_Object **argv)
if (fnum < 1)
scheme_signal_error(_("window index is out of range"));
- for (win = firstwin; win; win = win->w_next, --fnum)
+ for (win = firstwin; win != NULL; win = win->w_next, --fnum)
if (fnum == 1) /* to be 1-based */
return window_new(win);
diff --git a/src/if_python.c b/src/if_python.c
index d0ce4015a..dbbe602e0 100644
--- a/src/if_python.c
+++ b/src/if_python.c
@@ -2160,7 +2160,7 @@ WinListLength(PyObject *self)
win_T *w = firstwin;
int n = 0;
- while (w)
+ while (w != NULL)
{
++n;
w = W_NEXT(w);
@@ -2175,7 +2175,7 @@ WinListItem(PyObject *self, int n)
{
win_T *w;
- for (w = firstwin; w; w = W_NEXT(w), --n)
+ for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
if (n == 0)
return WindowNew(w);
diff --git a/src/if_ruby.c b/src/if_ruby.c
index f09b220ae..bacd6c72b 100644
--- a/src/if_ruby.c
+++ b/src/if_ruby.c
@@ -726,7 +726,7 @@ static VALUE window_s_count()
win_T *w;
int n = 0;
- for (w = firstwin; w; w = w->w_next)
+ for (w = firstwin; w != NULL; w = w->w_next)
n++;
return INT2NUM(n);
#else
diff --git a/src/main.c b/src/main.c
index 81e41b692..1a71be908 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1133,6 +1133,7 @@ getout(exitval)
#ifdef FEAT_AUTOCMD
buf_T *buf;
win_T *wp;
+ tabpage_T *tp, *next_tp;
#endif
exiting = TRUE;
@@ -1160,23 +1161,28 @@ getout(exitval)
#ifdef FEAT_AUTOCMD
/* Trigger BufWinLeave for all windows, but only once per buffer. */
- for (wp = firstwin; wp != NULL; )
+# if defined FEAT_WINDOWS
+ for (tp = first_tabpage; tp != NULL; tp = next_tp)
{
- buf = wp->w_buffer;
- if (buf->b_changedtick != -1)
+ next_tp = tp->tp_next;
+ for (wp = (tp->tp_topframe == topframe)
+ ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next)
{
- apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
+ buf = wp->w_buffer;
+ if (buf->b_changedtick != -1)
+ {
+ apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
FALSE, buf);
- buf->b_changedtick = -1; /* note that we did it already */
- wp = firstwin; /* restart, window may be closed */
+ buf->b_changedtick = -1; /* note that we did it already */
+ /* start all over, autocommands may mess up the lists */
+ next_tp = first_tabpage;
+ break;
+ }
}
-# ifdef FEAT_WINDOWS
- else
- wp = wp->w_next;
+ }
# else
- break;
+ apply_autocmds(EVENT_BUFWINLEAVE, curbuf, curbuf->b_fname, FALSE, curbuf);
# endif
- }
/* Trigger BufUnload for buffers that are loaded */
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
diff --git a/src/mark.c b/src/mark.c
index f077b1133..193d76846 100644
--- a/src/mark.c
+++ b/src/mark.c
@@ -1500,11 +1500,12 @@ write_viminfo_marks(fp_out)
int i;
#ifdef FEAT_WINDOWS
win_T *win;
+ tabpage_T *tp;
/*
* Set b_last_cursor for the all buffers that have a window.
*/
- for (win = firstwin; win != NULL; win = win->w_next)
+ FOR_ALL_TAB_WINDOWS(tp, win)
set_last_cursor(win);
#else
set_last_cursor(curwin);
diff --git a/src/misc1.c b/src/misc1.c
index 300aeffba..fc56c913a 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -2458,6 +2458,7 @@ changed()
ml_setflags(curbuf);
#ifdef FEAT_WINDOWS
check_status(curbuf);
+ redraw_tabpage = TRUE;
#endif
#ifdef FEAT_TITLE
need_maketitle = TRUE; /* set window title later */
@@ -2847,6 +2848,7 @@ unchanged(buf, ff)
save_file_ff(buf);
#ifdef FEAT_WINDOWS
check_status(buf);
+ redraw_tabpage = TRUE;
#endif
#ifdef FEAT_TITLE
need_maketitle = TRUE; /* set window title later */
diff --git a/src/misc2.c b/src/misc2.c
index 328bdf216..2ff4d5c58 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -2790,7 +2790,9 @@ set_fileformat(t, opt_flags)
set_string_option_direct((char_u *)"ff", -1, (char_u *)p,
OPT_FREE | opt_flags);
#ifdef FEAT_WINDOWS
+ /* This may cause the buffer to become (un)modified. */
check_status(curbuf);
+ redraw_tabpage = TRUE;
#endif
#ifdef FEAT_TITLE
need_maketitle = TRUE; /* set window title later */
diff --git a/src/normal.c b/src/normal.c
index d4001b494..d910bbe86 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -2421,6 +2421,37 @@ do_mouse(oap, c, dir, count, fixindent)
start_visual.lnum = 0;
+#ifdef FEAT_WINDOWS
+ /* Check for clicking in the tab page line. */
+ if (mouse_row == 0 && firstwin->w_winrow > 0)
+ {
+ got_click = FALSE; /* ignore mouse-up and drag events */
+
+ /* click in last column closes the current tab page. */
+ if (mouse_col == Columns - 1 && first_tabpage->tp_next != NULL)
+ {
+ tabpage_close(FALSE);
+ return TRUE;
+ }
+
+ /* click in a tab selects that tab page */
+ if (is_click
+# ifdef FEAT_CMDWIN
+ && cmdwin_type == 0
+# endif
+ && mouse_col < Columns && TabPageIdxs[mouse_col] != 0xff)
+ {
+ goto_tabpage(TabPageIdxs[mouse_col]);
+
+ /* It's like clicking on the status line of a window. */
+ if (curwin != old_curwin)
+ end_visual_mode();
+ return TRUE;
+ }
+ return FALSE;
+ }
+#endif
+
/*
* When 'mousemodel' is "popup" or "popup_setpos", translate mouse events:
* right button up -> pop-up menu
diff --git a/src/option.c b/src/option.c
index 25ddafbd2..e955f7f03 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2653,6 +2653,7 @@ static char *(p_cot_values[]) = {"menu", "longest", NULL};
static void set_option_default __ARGS((int, int opt_flags, int compatible));
static void set_options_default __ARGS((int opt_flags));
+static char_u *term_bg_default __ARGS((void));
static void did_set_option __ARGS((int opt_idx, int opt_flags, int new_value));
static char_u *illegal_char __ARGS((char_u *, int));
static int string_to_key __ARGS((char_u *arg));
@@ -3200,6 +3201,7 @@ set_options_default(opt_flags)
int i;
#ifdef FEAT_WINDOWS
win_T *wp;
+ tabpage_T *tp;
#endif
for (i = 0; !istermoption(&options[i]); i++)
@@ -3208,7 +3210,7 @@ set_options_default(opt_flags)
#ifdef FEAT_WINDOWS
/* The 'scroll' option must be computed for all windows. */
- for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ FOR_ALL_TAB_WINDOWS(tp, wp)
win_comp_scroll(wp);
#else
win_comp_scroll(curwin);
@@ -3306,39 +3308,20 @@ set_init_2()
p_window = Rows - 1;
set_number_default("window", Rows - 1);
+ /* For DOS console the default is always black. */
#if !((defined(MSDOS) || defined(OS2) || defined(WIN3264)) && !defined(FEAT_GUI))
+ /*
+ * If 'background' wasn't set by the user, try guessing the value,
+ * depending on the terminal name. Only need to check for terminals
+ * with a dark background, that can handle color.
+ */
+ idx = findoption((char_u *)"bg");
+ if (!(options[idx].flags & P_WAS_SET) && *term_bg_default() == 'd')
{
- char_u *p;
-
- /*
- * If 'background' wasn't set by the user, try guessing the value,
- * depending on the terminal name. Only need to check for terminals
- * with a dark background, that can handle color. Recognized are:
- * "linux" Linux console
- * "screen.linux" Linux console with screen
- * "cygwin" Cygwin shell
- * "putty" Putty program
- * We also check the COLORFGBG environment variable, which is set by
- * rxvt and derivatives. This variable contains either two or three
- * values separated by semicolons; we want the last value in either
- * case. If this value is 0-6 or 8, our background is dark.
- */
- idx = findoption((char_u *)"bg");
- if (!(options[idx].flags & P_WAS_SET)
- && (STRCMP(T_NAME, "linux") == 0
- || STRCMP(T_NAME, "screen.linux") == 0
- || STRCMP(T_NAME, "cygwin") == 0
- || STRCMP(T_NAME, "putty") == 0
- || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
- && (p = vim_strrchr(p, ';')) != NULL
- && ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
- && p[2] == NUL)))
- {
- set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE);
- /* don't mark it as set, when starting the GUI it may be
- * changed again */
- options[idx].flags &= ~P_WAS_SET;
- }
+ set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE);
+ /* don't mark it as set, when starting the GUI it may be
+ * changed again */
+ options[idx].flags &= ~P_WAS_SET;
}
#endif
@@ -3354,6 +3337,40 @@ set_init_2()
}
/*
+ * Return "dark" or "light" depending on the kind of terminal.
+ * This is just guessing! Recognized are:
+ * "linux" Linux console
+ * "screen.linux" Linux console with screen
+ * "cygwin" Cygwin shell
+ * "putty" Putty program
+ * We also check the COLORFGBG environment variable, which is set by
+ * rxvt and derivatives. This variable contains either two or three
+ * values separated by semicolons; we want the last value in either
+ * case. If this value is 0-6 or 8, our background is dark.
+ */
+ static char_u *
+term_bg_default()
+{
+ char_u *p;
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN3264)
+ /* DOS console nearly always black */
+ return (char_u *)"dark";
+#else
+ if (STRCMP(T_NAME, "linux") == 0
+ || STRCMP(T_NAME, "screen.linux") == 0
+ || STRCMP(T_NAME, "cygwin") == 0
+ || STRCMP(T_NAME, "putty") == 0
+ || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
+ && (p = vim_strrchr(p, ';')) != NULL
+ && ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
+ && p[2] == NUL))
+ return (char_u *)"dark";
+ return (char_u *)"light";
+#endif
+}
+
+/*
* Initialize the options, part three: After reading the .vimrc
*/
void
@@ -4071,8 +4088,7 @@ do_set(arg, opt_flags)
newval = gui_bg_default();
else
#endif
- if (STRCMP(T_NAME, "linux") == 0)
- newval = (char_u *)"dark";
+ newval = term_bg_default();
}
/* expand environment variables and ~ (since the
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index a6998cf50..a171e9730 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -23,6 +23,8 @@ char_u *get_user_cmd_nargs __ARGS((expand_T *xp, int idx));
char_u *get_user_cmd_complete __ARGS((expand_T *xp, int idx));
int parse_compl_arg __ARGS((char_u *value, int vallen, int *complp, long *argt, char_u **compl_arg));
void not_exiting __ARGS((void));
+void tabpage_close __ARGS((int forceit));
+void tabpage_close_other __ARGS((tabpage_T *tp, int forceit));
void handle_drop __ARGS((int filec, char_u **filev, int split));
void alist_clear __ARGS((alist_T *al));
void alist_init __ARGS((alist_T *al));
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 0ff745a08..ae6aa636f 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -6,15 +6,18 @@ int win_count __ARGS((void));
int make_windows __ARGS((int count, int vertical));
void win_move_after __ARGS((win_T *win1, win_T *win2));
void win_equal __ARGS((win_T *next_curwin, int current, int dir));
-void close_windows __ARGS((buf_T *buf));
+void close_windows __ARGS((buf_T *buf, int keep_curwin));
int last_window __ARGS((void));
void win_close __ARGS((win_T *win, int free_buf));
+void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp));
void win_free_all __ARGS((void));
void close_others __ARGS((int message, int forceit));
void win_init __ARGS((win_T *wp));
int win_alloc_first __ARGS((void));
void win_init_size __ARGS((void));
int win_new_tabpage __ARGS((void));
+int valid_tabpage __ARGS((tabpage_T *tpc));
+tabpage_T *find_tabpage __ARGS((int n));
void goto_tabpage __ARGS((int n));
void win_goto __ARGS((win_T *wp));
win_T *win_find_nr __ARGS((int winnr));
diff --git a/src/screen.c b/src/screen.c
index 9005efafd..f9ed5e17e 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -6742,6 +6742,10 @@ screenalloc(clear)
sattr_T *new_ScreenAttrs;
unsigned *new_LineOffset;
char_u *new_LineWraps;
+#ifdef FEAT_WINDOWS
+ char_u *new_TabPageIdxs;
+ tabpage_T *tp;
+#endif
static int entered = FALSE; /* avoid recursiveness */
static int did_outofmem_msg = FALSE; /* did outofmem message */
@@ -6788,10 +6792,10 @@ screenalloc(clear)
* size is wrong.
*/
#ifdef FEAT_WINDOWS
- for (wp = firstwin; wp; wp = wp->w_next)
+ FOR_ALL_TAB_WINDOWS(tp, wp)
win_free_lsize(wp);
#else
- win_free_lsize(curwin);
+ win_free_lsize(curwin);
#endif
new_ScreenLines = (schar_T *)lalloc((long_u)(
@@ -6815,6 +6819,9 @@ screenalloc(clear)
new_LineOffset = (unsigned *)lalloc((long_u)(
Rows * sizeof(unsigned)), FALSE);
new_LineWraps = (char_u *)lalloc((long_u)(Rows * sizeof(char_u)), FALSE);
+#ifdef FEAT_WINDOWS
+ new_TabPageIdxs = (char_u *)lalloc((long_u)(Columns * sizeof(char_u)), FALSE);
+#endif
FOR_ALL_WINDOWS(wp)
{
@@ -6836,6 +6843,9 @@ screenalloc(clear)
|| new_ScreenAttrs == NULL
|| new_LineOffset == NULL
|| new_LineWraps == NULL
+#ifdef FEAT_WINDOWS
+ || new_TabPageIdxs == NULL
+#endif
|| outofmem)
{
if (ScreenLines != NULL || !did_outofmem_msg)
@@ -6865,6 +6875,10 @@ screenalloc(clear)
new_LineOffset = NULL;
vim_free(new_LineWraps);
new_LineWraps = NULL;
+#ifdef FEAT_WINDOWS
+ vim_free(new_TabPageIdxs);
+ new_TabPageIdxs = NULL;
+#endif
}
else
{
@@ -6956,6 +6970,9 @@ screenalloc(clear)
ScreenAttrs = new_ScreenAttrs;
LineOffset = new_LineOffset;
LineWraps = new_LineWraps;
+#ifdef FEAT_WINDOWS
+ TabPageIdxs = new_TabPageIdxs;
+#endif
/* It's important that screen_Rows and screen_Columns reflect the actual
* size of ScreenLines[]. Set them before calling anything. */
@@ -7005,6 +7022,9 @@ free_screenlines()
vim_free(ScreenAttrs);
vim_free(LineOffset);
vim_free(LineWraps);
+#ifdef FEAT_WINDOWS
+ vim_free(TabPageIdxs);
+#endif
}
void
@@ -8443,9 +8463,13 @@ draw_tabpage()
tabpage_T *tp;
int tabwidth;
int col = 0;
+ int scol;
int had_current = FALSE;
int attr;
win_T *wp;
+ win_T *cwp;
+ int wincount;
+ int modified;
int c;
int len;
int attr_sel = hl_attr(HLF_TPS);
@@ -8460,13 +8484,16 @@ draw_tabpage()
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
++tabcount;
- tabwidth = Columns / tabcount;
+ tabwidth = (Columns - 1 + tabcount / 2) / tabcount;
if (tabwidth < 6)
tabwidth = 6;
attr = attr_nosel;
- for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ tabcount = 0;
+ for (tp = first_tabpage; tp != NULL && col < Columns; tp = tp->tp_next)
{
+ scol = col;
+
if (tp->tp_topframe == topframe)
{
c = '/';
@@ -8486,21 +8513,55 @@ draw_tabpage()
screen_putchar(' ', 0, col++, attr);
if (tp->tp_topframe == topframe)
- wp = curwin;
+ {
+ cwp = curwin;
+ wp = firstwin;
+ }
else
- wp = tp->tp_curwin;
- if (buf_spname(wp->w_buffer) != NULL)
- STRCPY(NameBuff, buf_spname(wp->w_buffer));
+ {
+ cwp = tp->tp_curwin;
+ wp = tp->tp_firstwin;
+ }
+
+ modified = FALSE;
+ 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 *)NameBuff, MAXPATHL, "#%d", wincount);
+ len = STRLEN(NameBuff);
+ screen_puts_len(NameBuff, len, 0, col, attr);
+ col += len;
+ }
+ if (modified)
+ screen_puts_len((char_u *)"+", 2, 0, col++, attr);
+ screen_putchar(' ', 0, col++, attr);
+ }
+
+ if (buf_spname(cwp->w_buffer) != NULL)
+ STRCPY(NameBuff, buf_spname(cwp->w_buffer));
else
- home_replace(wp->w_buffer, wp->w_buffer->b_fname, NameBuff,
+ home_replace(cwp->w_buffer, cwp->w_buffer->b_fname, NameBuff,
MAXPATHL, TRUE);
trans_characters(NameBuff, MAXPATHL);
len = STRLEN(NameBuff);
- if (len > tabwidth) /* TODO: multi-byte chars */
- len = tabwidth;
- screen_puts_len(NameBuff, len, 0, col, attr);
- col += len;
+ if (len > scol - col + tabwidth - 1) /* TODO: multi-byte chars */
+ len = scol - col + tabwidth - 1;
+ if (len > 0)
+ {
+ screen_puts_len(NameBuff, len, 0, col, attr);
+ col += len;
+ }
screen_putchar(' ', 0, col++, attr);
+
+ /* Store the tab page number in TabPageIdxs[], so that jump_to_mouse()
+ * knows where each one is. */
+ ++tabcount;
+ while (scol < col)
+ TabPageIdxs[scol++] = tabcount;
}
if (t_colors < 8)
@@ -8511,6 +8572,14 @@ draw_tabpage()
else
c = ' ';
screen_fill(0, 1, col, (int)Columns, c, c, attr_fill);
+
+ /* Put an "X" for closing the current tab if there are several. */
+ if (first_tabpage->tp_next != NULL)
+ screen_putchar('X', 0, (int)Columns - 1, attr_nosel);
+
+ /* Clicking outside of tabs has no effect. */
+ while (scol < Columns)
+ TabPageIdxs[scol++] = 0xff;
}
#endif
diff --git a/src/structs.h b/src/structs.h
index 893b826f9..6153099e6 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1558,6 +1558,7 @@ struct tabpage_S
tabpage_T *tp_next; /* next tabpage or NULL */
frame_T *tp_topframe; /* topframe for the windows */
win_T *tp_curwin; /* current window in this Tab page */
+ win_T *tp_prevwin; /* previous window in this Tab page */
win_T *tp_firstwin; /* first window in this Tab page */
win_T *tp_lastwin; /* last window in this Tab page */
long tp_old_Rows; /* Rows when Tab page was left */
diff --git a/src/version.h b/src/version.h
index 0f561bc61..b00a9a1c0 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 15)"
-#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 15, compiled "
+#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 16)"
+#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 16, compiled "
diff --git a/src/window.c b/src/window.c
index 116a5fc7f..927c7a15e 100644
--- a/src/window.c
+++ b/src/window.c
@@ -25,9 +25,9 @@ static void win_exchange __ARGS((long));
static void win_rotate __ARGS((int, int));
static void win_totop __ARGS((int size, int flags));
static void win_equal_rec __ARGS((win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height));
-static win_T *win_free_mem __ARGS((win_T *win, int *dirp));
-static win_T *winframe_remove __ARGS((win_T *win, int *dirp));
-static frame_T *win_altframe __ARGS((win_T *win));
+static win_T *win_free_mem __ARGS((win_T *win, int *dirp, tabpage_T *tp));
+static win_T *winframe_remove __ARGS((win_T *win, int *dirp, tabpage_T *tp));
+static frame_T *win_altframe __ARGS((win_T *win, tabpage_T *tp));
static tabpage_T *alt_tabpage __ARGS((void));
static win_T *frame2win __ARGS((frame_T *frp));
static int frame_has_win __ARGS((frame_T *frp, win_T *wp));
@@ -49,9 +49,9 @@ static void enter_tabpage __ARGS((tabpage_T *tp, buf_T *old_curbuf));
static void frame_fix_height __ARGS((win_T *wp));
static int frame_minheight __ARGS((frame_T *topfrp, win_T *next_curwin));
static void win_enter_ext __ARGS((win_T *wp, int undo_sync, int no_curwin));
-static void win_free __ARGS((win_T *wp));
+static void win_free __ARGS((win_T *wp, tabpage_T *tp));
static void win_append __ARGS((win_T *, win_T *));
-static void win_remove __ARGS((win_T *));
+static void win_remove __ARGS((win_T *, tabpage_T *tp));
static void frame_append __ARGS((frame_T *after, frame_T *frp));
static void frame_insert __ARGS((frame_T *before, frame_T *frp));
static void frame_remove __ARGS((frame_T *frp));
@@ -1262,14 +1262,14 @@ win_exchange(Prenum)
frp2 = curwin->w_frame->fr_prev;
if (wp->w_prev != curwin)
{
- win_remove(curwin);
+ win_remove(curwin, NULL);
frame_remove(curwin->w_frame);
win_append(wp->w_prev, curwin);
frame_insert(frp, curwin->w_frame);
}
if (wp != wp2)
{
- win_remove(wp);
+ win_remove(wp, NULL);
frame_remove(wp->w_frame);
win_append(wp2, wp);
if (frp2 == NULL)
@@ -1353,7 +1353,7 @@ win_rotate(upwards, count)
/* remove first window/frame from the list */
frp = curwin->w_frame->fr_parent->fr_child;
wp1 = frp->fr_win;
- win_remove(wp1);
+ win_remove(wp1, NULL);
frame_remove(frp);
/* find last frame and append removed window/frame after it */
@@ -1372,7 +1372,7 @@ win_rotate(upwards, count)
;
wp1 = frp->fr_win;
wp2 = wp1->w_prev; /* will become last window */
- win_remove(wp1);
+ win_remove(wp1, NULL);
frame_remove(frp);
/* append the removed window/frame before the first in the list */
@@ -1419,8 +1419,8 @@ win_totop(size, flags)
}
/* Remove the window and frame from the tree of frames. */
- (void)winframe_remove(curwin, &dir);
- win_remove(curwin);
+ (void)winframe_remove(curwin, &dir, NULL);
+ win_remove(curwin, NULL);
last_status(FALSE); /* may need to remove last status line */
(void)win_comp_pos(); /* recompute window positions */
@@ -1486,7 +1486,7 @@ win_move_after(win1, win2)
win1->w_vsep_width = 0;
#endif
}
- win_remove(win1);
+ win_remove(win1, NULL);
frame_remove(win1->w_frame);
win_append(win2, win1);
frame_append(win2->w_frame, win1->w_frame);
@@ -1797,23 +1797,50 @@ win_equal_rec(next_curwin, current, topfr, dir, col, row, width, height)
* close all windows for buffer 'buf'
*/
void
-close_windows(buf)
+close_windows(buf, keep_curwin)
buf_T *buf;
+ int keep_curwin; /* don't close "curwin" */
{
- win_T *win;
+ win_T *wp;
+ tabpage_T *tp, *nexttp;
+ int h = tabpageline_height();
++RedrawingDisabled;
- for (win = firstwin; win != NULL && lastwin != firstwin; )
+
+ for (wp = firstwin; wp != NULL && lastwin != firstwin; )
{
- if (win->w_buffer == buf)
+ if (wp->w_buffer == buf && (!keep_curwin || wp != curwin))
{
- win_close(win, FALSE);
- win = firstwin; /* go back to the start */
+ win_close(wp, FALSE);
+
+ /* Start all over, autocommands may change the window layout. */
+ wp = firstwin;
}
else
- win = win->w_next;
+ wp = wp->w_next;
}
+
+ /* Also check windows in other tab pages. */
+ for (tp = first_tabpage; tp != NULL; tp = nexttp)
+ {
+ nexttp = tp->tp_next;
+ if (tp->tp_topframe != topframe)
+ for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_buffer == buf)
+ {
+ win_close_othertab(wp, FALSE, tp);
+
+ /* Start all over, the tab page may be closed and
+ * autocommands may change the window layout. */
+ nexttp = first_tabpage;
+ break;
+ }
+ }
+
--RedrawingDisabled;
+
+ if (h != tabpageline_height())
+ shell_new_rows();
}
/*
@@ -1827,7 +1854,7 @@ last_window()
}
/*
- * close window "win"
+ * Close window "win".
* If "free_buf" is TRUE related buffer may be unloaded.
*
* called by :quit, :close, :xit, :wq and findtag()
@@ -1866,7 +1893,7 @@ win_close(win, free_buf)
* Guess which window is going to be the new current window.
* This may change because of the autocommands (sigh).
*/
- wp = frame2win(win_altframe(win));
+ wp = frame2win(win_altframe(win, NULL));
/*
* Be careful: If autocommands delete the window, return now.
@@ -1899,7 +1926,7 @@ win_close(win, free_buf)
return;
/* Free the memory used for the window. */
- wp = win_free_mem(win, &dir);
+ wp = win_free_mem(win, &dir, NULL);
/* When closing the last window in a tab page go to another tab page. */
if (wp == NULL)
@@ -2004,13 +2031,70 @@ win_close(win, free_buf)
}
/*
+ * Close window "win" in tab page "tp", which is not the current tab page.
+ * This may be the last window ih that tab page and result in closing the tab,
+ * thus "tp" may become invalid!
+ * Called must check if buffer is hidden.
+ */
+ void
+win_close_othertab(win, free_buf, tp)
+ win_T *win;
+ int free_buf;
+ tabpage_T *tp;
+{
+ win_T *wp;
+ int dir;
+ tabpage_T *ptp = NULL;
+
+ /* Close the link to the buffer. */
+ close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0);
+
+ /* Careful: Autocommands may have closed the tab page or made it the
+ * current tab page. */
+ for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next)
+ ;
+ if (ptp == NULL || tp->tp_topframe == topframe)
+ return;
+
+ /* Autocommands may have closed the window already. */
+ for (wp = tp->tp_firstwin; wp != NULL && wp != win; wp = wp->w_next)
+ ;
+ if (wp == NULL)
+ return;
+
+ /* Free the memory used for the window. */
+ wp = win_free_mem(win, &dir, tp);
+
+ /* When closing the last window in a tab page remove the tab page. */
+ if (wp == NULL)
+ {
+ if (tp == first_tabpage)
+ first_tabpage = tp->tp_next;
+ else
+ {
+ for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tp;
+ ptp = ptp->tp_next)
+ ;
+ if (ptp == NULL)
+ {
+ EMSG2(_(e_intern2), "win_close_othertab()");
+ return;
+ }
+ ptp->tp_next = tp->tp_next;
+ }
+ vim_free(tp);
+ }
+}
+
+/*
* Free the memory used for a window.
* Returns a pointer to the window that got the freed up space.
*/
static win_T *
-win_free_mem(win, dirp)
+win_free_mem(win, dirp, tp)
win_T *win;
int *dirp; /* set to 'v' or 'h' for direction if 'ea' */
+ tabpage_T *tp; /* tab page "win" is in, NULL for current */
{
frame_T *frp;
win_T *wp;
@@ -2024,13 +2108,9 @@ win_free_mem(win, dirp)
/* Remove the window and its frame from the tree of frames. */
frp = win->w_frame;
- if (firstwin == lastwin)
- /* Last window in a tab page. */
- wp = NULL;
- else
- wp = winframe_remove(win, dirp);
+ wp = winframe_remove(win, dirp, tp);
vim_free(frp);
- win_free(win);
+ win_free(win, tp);
return wp;
}
@@ -2041,8 +2121,13 @@ win_free_all()
{
int dummy;
+# ifdef FEAT_WINDOWS
+ while (first_tabpage->tp_next != NULL)
+ tabpage_close(TRUE);
+# endif
+
while (firstwin != NULL)
- (void)win_free_mem(firstwin, &dummy);
+ (void)win_free_mem(firstwin, &dummy, NULL);
}
#endif
@@ -2052,9 +2137,10 @@ win_free_all()
*/
/*ARGSUSED*/
static win_T *
-winframe_remove(win, dirp)
+winframe_remove(win, dirp, tp)
win_T *win;
int *dirp; /* set to 'v' or 'h' for direction if 'ea' */
+ tabpage_T *tp; /* tab page "win" is in, NULL for current */
{
frame_T *frp, *frp2, *frp3;
frame_T *frp_close = win->w_frame;
@@ -2062,12 +2148,15 @@ winframe_remove(win, dirp)
int old_height = 0;
/*
- * Remove the window from its frame.
+ * If there is only one window there is nothing to remove.
*/
- frp2 = win_altframe(win);
- if (frp2 == NULL)
- return NULL; /* deleted the last frame */
+ if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
+ return NULL;
+ /*
+ * Remove the window from its frame.
+ */
+ frp2 = win_altframe(win, tp);
wp = frame2win(frp2);
/* Remove this frame from the list of frames. */
@@ -2160,13 +2249,14 @@ winframe_remove(win, dirp)
* layout.
*/
static frame_T *
-win_altframe(win)
+win_altframe(win, tp)
win_T *win;
+ tabpage_T *tp; /* tab page "win" is in, NULL for current */
{
frame_T *frp;
int b;
- if (firstwin == lastwin)
+ if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
/* Last window in this tab page, will go to next tab page. */
return alt_tabpage()->tp_curwin->w_frame;
@@ -2861,6 +2951,7 @@ win_new_tabpage()
firstwin->w_winrow = tabpageline_height();
newtp->tp_topframe = topframe;
+ last_status(FALSE);
redraw_all_later(CLEAR);
return OK;
}
@@ -2868,6 +2959,7 @@ win_new_tabpage()
/* Failed, get back the previous Tab page */
topframe = tp->tp_topframe;
curwin = tp->tp_curwin;
+ prevwin = tp->tp_prevwin;
firstwin = tp->tp_firstwin;
lastwin = tp->tp_lastwin;
return FAIL;
@@ -2890,6 +2982,36 @@ current_tabpage()
}
/*
+ * Return TRUE when "tpc" points to a valid tab page.
+ */
+ int
+valid_tabpage(tpc)
+ tabpage_T *tpc;
+{
+ tabpage_T *tp;
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ if (tp == tpc)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Find tab page "n" (first one is 1). Returns NULL when not found.
+ */
+ tabpage_T *
+find_tabpage(n)
+ int n;
+{
+ tabpage_T *tp;
+ int i = 1;
+
+ for (tp = first_tabpage; tp != NULL && i != n; tp = tp->tp_next)
+ ++i;
+ return tp;
+}
+
+/*
* Prepare for leaving the current tab page "tp".
*/
static void
@@ -2902,6 +3024,7 @@ leave_tabpage(tp)
gui_remove_scrollbars();
#endif
tp->tp_curwin = curwin;
+ tp->tp_prevwin = prevwin;
tp->tp_firstwin = firstwin;
tp->tp_lastwin = lastwin;
tp->tp_old_Rows = Rows;
@@ -2925,6 +3048,7 @@ enter_tabpage(tp, old_curbuf)
lastwin = tp->tp_lastwin;
topframe = tp->tp_topframe;
win_enter_ext(tp->tp_curwin, FALSE, TRUE);
+ prevwin = tp->tp_prevwin;
#ifdef FEAT_AUTOCMD
if (old_curbuf != curbuf)
@@ -2985,12 +3109,13 @@ goto_tabpage(n)
{
/* Go to tab page "n". */
i = 0;
- for (tp = first_tabpage; ++i != n; tp = tp->tp_next)
- if (tp == NULL)
- {
- beep_flush();
- return;
- }
+ for (tp = first_tabpage; ++i != n && tp != NULL; tp = tp->tp_next)
+ ;
+ if (tp == NULL)
+ {
+ beep_flush();
+ return;
+ }
}
leave_tabpage(otp);
@@ -3418,8 +3543,9 @@ win_alloc(after)
* remove window 'wp' from the window list and free the structure
*/
static void
-win_free(wp)
+win_free(wp, tp)
win_T *wp;
+ tabpage_T *tp; /* tab page "win" is in, NULL for current */
{
int i;
@@ -3478,7 +3604,7 @@ win_free(wp)
}
#endif /* FEAT_GUI */
- win_remove(wp);
+ win_remove(wp, tp);
vim_free(wp);
}
@@ -3512,17 +3638,22 @@ win_append(after, wp)
* Remove a window from the window list.
*/
static void
-win_remove(wp)
+win_remove(wp, tp)
win_T *wp;
+ tabpage_T *tp; /* tab page "win" is in, NULL for current */
{
if (wp->w_prev != NULL)
wp->w_prev->w_next = wp->w_next;
- else
+ else if (tp == NULL)
firstwin = wp->w_next;
+ else
+ tp->tp_firstwin = wp->w_next;
if (wp->w_next != NULL)
wp->w_next->w_prev = wp->w_prev;
- else
+ else if (tp == NULL)
lastwin = wp->w_prev;
+ else
+ tp->tp_lastwin = wp->w_prev;
}
/*
@@ -3600,6 +3731,7 @@ win_free_lsize(wp)
/*
* Called from win_new_shellsize() after Rows changed.
+ * This only does the current tab page, others must be done when made active.
*/
void
shell_new_rows()
@@ -5115,16 +5247,27 @@ vim_FullName(fname, buf, len, force)
min_rows()
{
int total;
+#ifdef FEAT_WINDOWS
+ tabpage_T *tp;
+ int n;
+#endif
if (firstwin == NULL) /* not initialized yet */
return MIN_LINES;
- total = 1; /* count the room for the command line */
#ifdef FEAT_WINDOWS
- total += frame_minheight(topframe, NULL);
+ total = 0;
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ {
+ n = frame_minheight(tp->tp_topframe, NULL);
+ if (total < n)
+ total = n;
+ }
+ total += tabpageline_height();
#else
- total += 1; /* at least one window should have a line! */
+ total = 1; /* at least one window should have a line! */
#endif
+ total += 1; /* count the room for the command line */
return total;
}
@@ -5169,7 +5312,9 @@ check_lnums(do_curwin)
win_T *wp;
#ifdef FEAT_WINDOWS
- for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ tabpage_T *tp;
+
+ FOR_ALL_TAB_WINDOWS(tp, wp)
if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf)
#else
wp = curwin;