]> granicus.if.org Git - vim/commitdiff
updated for version 7.0202
authorBram Moolenaar <Bram@vim.org>
Mon, 20 Feb 2006 21:27:21 +0000 (21:27 +0000)
committerBram Moolenaar <Bram@vim.org>
Mon, 20 Feb 2006 21:27:21 +0000 (21:27 +0000)
runtime/doc/tabpage.txt
src/buffer.c
src/ex_docmd.c
src/os_mac.h
src/proto/buffer.pro
src/vim.h
src/window.c

index cf95ca2176680334ab134d582efe53f093785072..b7cd51bd8617468632657127d5283f1c6e5eb146 100644 (file)
@@ -1,10 +1,10 @@
-*tabpage.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 18
+*tabpage.txt*   For Vim version 7.0aa.  Last change: 2006 Feb 20
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
 
 
-Editing with windows in multuple tab pages.            *tab-page* *tabpage*
+Editing with windows in multiple tab pages.            *tab-page* *tabpage*
 
 The commands which have been added to use multiple tab pages are explained
 here.  Additionally, there are explanations for commands that work differently
@@ -45,14 +45,14 @@ OPENING A NEW TAB PAGE:
 When starting Vim "vim -p filename ..." opens each file argument in a separate
 tab page (up to 10). |-p|
 
-:tabe[dit]                                             *:tabe* *:tabedit*
+:tabe[dit]                             *:tabe* *:tabedit* *:tabn* *:tabnew*
 :tabn[ew]      Open a new tab page with an empty window.
 
 :tabe[dit] [++opt] [+cmd] {file}
 :tabn[ew] [++opt] [+cmd] {file}
                Open a new tab page and edit {file}, like with |:edit|.
 
-:tabf[ind] [++opt] [+cmd] {file}
+:tabf[ind] [++opt] [+cmd] {file}                       *:tabf* *:tabfind*
                Open a new tab page and edit {file} in 'path', like with
                |:find|.
                {not available when the |+file_in_path| feature was disabled
@@ -114,12 +114,32 @@ Other commands:
 You can use the 'tabline' option to specify when you want the line with tab
 page labels to appear: never, when there is more than one tab page or always.
 
+The highlighting of the tab pages line is set with the groups TabLine
+TabLineSel and TabLineFill.  |hl-TabLine| |hl-TabLineSel| |hl-TabLineFill|
+
 Diff mode works per tab page.  You can see the diffs between several files
 within one tab page.  Other tab pages can show differences between other
 files.
 
-The TabLeavePre and TabEnterPost autocommand events can be used to do
-something when switching from one tab page to another.
+The TabLeave and TabEnter autocommand events can be used to do something when
+switching from one tab page to another.  The exact order depends on what you
+are doing.  When creating a new tab page this works as if you create a new
+window on the same buffer and then edit another buffer.  Thus ":tabnew"
+triggers:
+       WinLeave                leave current window
+       TabLeave                leave current tab page
+       TabEnter                enter new tab page
+       WinEnter                enter window in new tab page
+       BufLeave                leave current buffer
+       BufEnter                enter new empty buffer
+
+For switching to another tab page the order is:
+       BufLeave
+       WinLeave
+       TabLeave
+       TabEnter
+       WinEnter
+       BufEnter
 
 
  vim:tw=78:ts=8:ft=help:norl:
index 2b6fe28105fc56f4331e821c57cb89977007c792..9af8d507d2688047c1a03a94f222bf3f44ff797f 100644 (file)
@@ -3018,9 +3018,15 @@ maketitle()
        if (*p_titlestring != NUL)
        {
 #ifdef FEAT_STL_OPT
+           int     use_sandbox = FALSE;
+
+# ifdef FEAT_EVAL
+           use_sandbox = was_set_insecurely((char_u *)"titlestring");
+# endif
            if (stl_syntax & STL_IN_TITLE)
                build_stl_str_hl(curwin, t_str, sizeof(buf),
-                                             p_titlestring, 0, maxlen, NULL);
+                                             p_titlestring, use_sandbox,
+                                             0, maxlen, NULL);
            else
 #endif
                t_str = p_titlestring;
@@ -3109,9 +3115,15 @@ maketitle()
        if (*p_iconstring != NUL)
        {
 #ifdef FEAT_STL_OPT
+           int     use_sandbox = FALSE;
+
+# ifdef FEAT_EVAL
+           use_sandbox = was_set_insecurely((char_u *)"iconstring");
+# endif
            if (stl_syntax & STL_IN_ICON)
                build_stl_str_hl(curwin, i_str, sizeof(buf),
-                                                   p_iconstring, 0, 0, NULL);
+                                                   p_iconstring, use_sandbox,
+                                                   0, 0, NULL);
            else
 #endif
                i_str = p_iconstring;
@@ -3190,9 +3202,12 @@ free_titles()
 
 #if defined(FEAT_STL_OPT) || defined(PROTO)
 /*
- * Build a string from the status line items in fmt.
+ * Build a string from the status line items in "fmt".
  * Return length of string in screen cells.
  *
+ * Normally works for window "wp", except when working for 'tabline' then it
+ * is "curwin".
+ *
  * Items are drawn interspersed with the text that surrounds it
  * Specials: %-<wid>(xxx%) => group, %= => middle marker, %< => truncation
  * Item: %-<minwid>.<maxwid><itemch> All but <itemch> are optional
@@ -3201,11 +3216,12 @@ free_titles()
  * or truncated if too long, fillchar is used for all whitespace.
  */
     int
-build_stl_str_hl(wp, out, outlen, fmt, fillchar, maxwidth, hl)
+build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar, maxwidth, hl)
     win_T      *wp;
     char_u     *out;           /* buffer to write into */
     size_t     outlen;         /* length of out[] */
     char_u     *fmt;
+    int                use_sandbox;    /* "fmt" was set insecurely, use sandbox */
     int                fillchar;
     int                maxwidth;
     struct stl_hlrec *hl;
@@ -3501,8 +3517,7 @@ build_stl_str_hl(wp, out, outlen, fmt, fillchar, maxwidth, hl)
            curwin = wp;
            curbuf = wp->w_buffer;
 
-           str = eval_to_string_safe(p, &t,
-                                 was_set_insecurely((char_u *)"statusline"));
+           str = eval_to_string_safe(p, &t, use_sandbox);
 
            curwin = o_curwin;
            curbuf = o_curbuf;
index 1a8788684f2244a7295001d9d2eb4ecfeab2a2c9..1eefcd892eb955bcb26ffbc0d19d8355be3901b7 100644 (file)
@@ -163,7 +163,6 @@ static void ex_tabs __ARGS((exarg_T *eap));
 # define ex_resize             ex_ni
 # define ex_splitview          ex_ni
 # define ex_stag               ex_ni
-# define ex_tabedit            ex_ni
 # define ex_tab                        ex_ni
 # define ex_tabs               ex_ni
 # define ex_tabclose           ex_ni
@@ -6305,7 +6304,8 @@ tabpage_close(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)
+       close_others(TRUE, forceit);
     if (lastwin == firstwin)
        ex_win_close(forceit, curwin, NULL);
 # ifdef FEAT_GUI
@@ -6863,12 +6863,17 @@ ex_wrongmodifier(eap)
  * :new [[+command] file]      split window with no or new file
  * :vnew [[+command] file]     split vertically window with no or new file
  * :sfind [+command] file      split window with file in 'path'
+ *
+ * :tabedit                    open new Tab page with empty window
+ * :tabedit [+command] file    open new Tab page and edit "file"
+ * :tabnew [[+command] file]   just like :tabedit
+ * :tabfind [+command] file    open new Tab page and find "file"
  */
     void
 ex_splitview(eap)
     exarg_T    *eap;
 {
-    win_T      *old_curwin;
+    win_T      *old_curwin = curwin;
 # if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
     char_u     *fname = NULL;
 # endif
@@ -6884,7 +6889,6 @@ ex_splitview(eap)
     }
 # endif
 
-    old_curwin = curwin;
 # ifdef FEAT_GUI
     need_mouse_correct = TRUE;
 # endif
@@ -6904,7 +6908,7 @@ ex_splitview(eap)
 # endif
 
 # ifdef FEAT_SEARCHPATH
-    if (eap->cmdidx == CMD_sfind)
+    if (eap->cmdidx == CMD_sfind || eap->cmdidx == CMD_tabfind)
     {
        fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg),
                                          FNAME_MESS, TRUE, curbuf->b_ffname);
@@ -6946,7 +6950,26 @@ ex_splitview(eap)
     cmdmod.browse = FALSE;     /* Don't browse again in do_ecmd(). */
 # endif
 
-    if (win_split(eap->addr_count > 0 ? (int)eap->line2 : 0,
+    /*
+     * Either open new tab page or split the window.
+     */
+    if (eap->cmdidx == CMD_tabedit
+           || eap->cmdidx == CMD_tabfind
+           || eap->cmdidx == CMD_tabnew)
+    {
+       if (win_new_tabpage() != FAIL)
+       {
+           do_exedit(eap, NULL);
+
+           /* set the alternate buffer for the window we came from */
+           if (curwin != old_curwin
+                   && win_valid(old_curwin)
+                   && old_curwin->w_buffer != curbuf
+                   && !cmdmod.keepalt)
+               old_curwin->w_alt_fnum = curbuf->b_fnum;
+       }
+    }
+    else if (win_split(eap->addr_count > 0 ? (int)eap->line2 : 0,
                                     *eap->cmd == 'v' ? WSP_VERT : 0) != FAIL)
     {
 # ifdef FEAT_SCROLLBIND
@@ -6974,85 +6997,6 @@ theend:
 # endif
 }
 
-/*
- * :tabedit                    open new Tab page with empty window
- * :tabedit [+command] file    open new Tab page and edit "file"
- * :tabnew [[+command] file]   just like :tabedit
- * :tabfind [+command] file    open new Tab page and find "file"
- */
-    void
-ex_tabedit(eap)
-    exarg_T    *eap;
-{
-# if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
-    char_u     *fname = NULL;
-# endif
-# ifdef FEAT_BROWSE
-    int                browse_flag = cmdmod.browse;
-# endif
-
-# ifdef FEAT_GUI
-    need_mouse_correct = TRUE;
-# endif
-
-# ifdef FEAT_SEARCHPATH
-    if (eap->cmdidx == CMD_tabfind)
-    {
-       fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg),
-                                         FNAME_MESS, TRUE, curbuf->b_ffname);
-       if (fname == NULL)
-           goto theend;
-       eap->arg = fname;
-    }
-#  ifdef FEAT_BROWSE
-    else
-#  endif
-# endif
-# ifdef FEAT_BROWSE
-    if (cmdmod.browse)
-    {
-       if (
-#  ifdef FEAT_GUI
-           !gui.in_use &&
-#  endif
-               au_has_group((char_u *)"FileExplorer"))
-       {
-           /* No browsing supported but we do have the file explorer:
-            * Edit the directory. */
-           if (*eap->arg == NUL || !mch_isdir(eap->arg))
-               eap->arg = (char_u *)".";
-       }
-       else
-       {
-           fname = do_browse(0, (char_u *)_("Edit File in new tab page"),
-                                         eap->arg, NULL, NULL, NULL, curbuf);
-           if (fname == NULL)
-               goto theend;
-           eap->arg = fname;
-       }
-    }
-    cmdmod.browse = FALSE;     /* Don't browse again in do_ecmd(). */
-# endif
-
-    if (win_new_tabpage() != FAIL)
-    {
-# ifdef FEAT_SCROLLBIND
-       curwin->w_p_scb = FALSE;
-# endif
-       if (*eap->arg != NUL)
-           do_exedit(eap, NULL);
-    }
-
-# ifdef FEAT_BROWSE
-    cmdmod.browse = browse_flag;
-# endif
-
-# if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE)
-theend:
-    vim_free(fname);
-# endif
-}
-
 /*
  * :tab command
  */
@@ -7316,12 +7260,14 @@ do_exedit(eap, old_curwin)
     }
 
     if ((eap->cmdidx == CMD_new
+               || eap->cmdidx == CMD_tabnew
+               || eap->cmdidx == CMD_tabedit
 #ifdef FEAT_VERTSPLIT
                || eap->cmdidx == CMD_vnew
 #endif
                ) && *eap->arg == NUL)
     {
-       /* ":new" without argument: edit an new empty buffer */
+       /* ":new" or ":tabnew" without argument: edit an new empty buffer */
        setpcmark();
        (void)do_ecmd(0, NULL, NULL, eap, ECMD_ONE,
                               ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0));
index 5e286594fb05bb5ef4d7caf6c61abd433d2e45e8..82d91a8e6fdbf9ceac935727b54b87a689b110b1 100644 (file)
  */
 
 /* Got problem trying to use shared library in 68k */
-#if !defined(__POWERPC__) && defined(FEAT_PYTHON)
+#if !defined(__POWERPC__) && !defined(__i386__) && defined(FEAT_PYTHON)
 # undef FEAT_PYTHON
 # warning Auto-disabling Python. Not yet supported in 68k.
 #endif
 
-#if !defined(__POWERPC__) && !defined(__ppc__)
+#if !defined(__POWERPC__) && !defined(__ppc__) && !defined(__i386__)
 # if !__option(enumsalwaysint)
 #  error "You must compile with enums always int!"
 # endif
index 1061e367f1d47a2c8a3482e1013cda2c7dbf78ba..07ec64c06c42831c84d0f37c84caa32689a4d5c2 100644 (file)
@@ -40,7 +40,7 @@ void col_print __ARGS((char_u *buf, int col, int vcol));
 void maketitle __ARGS((void));
 void resettitle __ARGS((void));
 void free_titles __ARGS((void));
-int build_stl_str_hl __ARGS((win_T *wp, char_u *out, size_t outlen, char_u *fmt, int fillchar, int maxwidth, struct stl_hlrec *hl));
+int build_stl_str_hl __ARGS((win_T *wp, char_u *out, size_t outlen, char_u *fmt, int insecure, int fillchar, int maxwidth, struct stl_hlrec *hl));
 void get_rel_pos __ARGS((win_T *wp, char_u *str));
 int append_arg_number __ARGS((win_T *wp, char_u *buf, int add_file, int maxlen));
 char_u *fix_fname __ARGS((char_u *fname));
index ef86e81bb9f4049a1f1cb72586ae52c5f62a2f8c..e4e26df6c1209f575b830dadde81a05205d4ffc9 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
 # endif
 #endif
 #ifdef MACOS
-# if defined(__POWERPC__) || defined(__fourbyteints__) \
+# if defined(__POWERPC__) || defined(MACOS_X) || defined(__fourbyteints__) \
   || defined(__MRC__) || defined(__SC__) || defined(__APPLE_CC__)/* MPW Compilers */
 #  define SIZEOF_INT 4
 # else
@@ -1109,8 +1109,8 @@ enum auto_event
     EVENT_SPELLFILEMISSING,    /* spell file missing */
     EVENT_CURSORMOVED,         /* cursor was moved */
     EVENT_CURSORMOVEDI,                /* cursor was moved in Insert mode */
-    EVENT_TABLEAVEPRE,         /* before leaving a tab page */
-    EVENT_TABENTERPOST,                /* after entering a tab page */
+    EVENT_TABLEAVE,            /* before leaving a tab page */
+    EVENT_TABENTER,            /* after entering a tab page */
     NUM_EVENTS                 /* MUST be the last one */
 };
 
index b117fe32c1c931d056d772b220dbb453304906ab..3419a01e0fe935b1342f4971f48442cb838d9fc9 100644 (file)
@@ -16,6 +16,7 @@
 static int path_is_url __ARGS((char_u *p));
 #if defined(FEAT_WINDOWS) || defined(PROTO)
 static int win_split_ins __ARGS((int size, int flags, win_T *newwin, int dir));
+static void win_init __ARGS((win_T *newp, win_T *oldp));
 static void frame_comp_pos __ARGS((frame_T *topfrp, int *row, int *col));
 static void frame_setheight __ARGS((frame_T *curfrp, int height));
 #ifdef FEAT_VERTSPLIT
@@ -42,7 +43,7 @@ static int frame_minwidth __ARGS((frame_T *topfrp, win_T *next_curwin));
 static void frame_fix_width __ARGS((win_T *wp));
 #endif
 #endif
-static int win_alloc_firstwin __ARGS((void));
+static int win_alloc_firstwin __ARGS((win_T *oldwin));
 #if defined(FEAT_WINDOWS) || defined(PROTO)
 static tabpage_T *alloc_tabpage __ARGS((void));
 static void free_tabpage __ARGS((tabpage_T *tp));
@@ -67,7 +68,7 @@ static void last_status_rec __ARGS((frame_T *fr, int statusline));
 
 static void make_snapshot __ARGS((void));
 static void make_snapshot_rec __ARGS((frame_T *fr, frame_T **frp));
-static void clear_snapshot __ARGS((void));
+static void clear_snapshot __ARGS((tabpage_T *tp));
 static void clear_snapshot_rec __ARGS((frame_T *fr));
 static void restore_snapshot __ARGS((int close_curwin));
 static int check_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
@@ -627,13 +628,13 @@ win_split(size, flags)
     if (flags & WSP_HELP)
        make_snapshot();
     else
-       clear_snapshot();
+       clear_snapshot(curtab);
 
     return win_split_ins(size, flags, NULL, 0);
 }
 
 /*
- * When "newwin" is NULL: split a window in two.
+ * When "newwin" is NULL: split the current window in two.
  * When "newwin" is not NULL: insert this window at the far
  * top/left/right/bottom.
  * return FAIL for failure, OK otherwise
@@ -807,55 +808,8 @@ win_split_ins(size, flags, newwin, dir)
        if (wp == NULL)
            return FAIL;
 
-       /*
-        * make the contents of the new window the same as the current one
-        */
-       wp->w_buffer = curbuf;
-       curbuf->b_nwindows++;
-       wp->w_cursor = curwin->w_cursor;
-       wp->w_valid = 0;
-       wp->w_curswant = curwin->w_curswant;
-       wp->w_set_curswant = curwin->w_set_curswant;
-       wp->w_topline = curwin->w_topline;
-#ifdef FEAT_DIFF
-       wp->w_topfill = curwin->w_topfill;
-#endif
-       wp->w_leftcol = curwin->w_leftcol;
-       wp->w_pcmark = curwin->w_pcmark;
-       wp->w_prev_pcmark = curwin->w_prev_pcmark;
-       wp->w_alt_fnum = curwin->w_alt_fnum;
-       wp->w_fraction = curwin->w_fraction;
-       wp->w_prev_fraction_row = curwin->w_prev_fraction_row;
-#ifdef FEAT_JUMPLIST
-       copy_jumplist(curwin, wp);
-#endif
-#ifdef FEAT_QUICKFIX
-       copy_loclist(curwin, wp);
-#endif
-       if (curwin->w_localdir != NULL)
-           wp->w_localdir = vim_strsave(curwin->w_localdir);
-
-       /* Use the same argument list. */
-       wp->w_alist = curwin->w_alist;
-       ++wp->w_alist->al_refcount;
-       wp->w_arg_idx = curwin->w_arg_idx;
-
-       /*
-        * copy tagstack and options from existing window
-        */
-       for (i = 0; i < curwin->w_tagstacklen; i++)
-       {
-           wp->w_tagstack[i] = curwin->w_tagstack[i];
-           if (wp->w_tagstack[i].tagname != NULL)
-               wp->w_tagstack[i].tagname =
-                                      vim_strsave(wp->w_tagstack[i].tagname);
-       }
-       wp->w_tagstackidx = curwin->w_tagstackidx;
-       wp->w_tagstacklen = curwin->w_tagstacklen;
-       win_copy_options(curwin, wp);
-#ifdef FEAT_FOLDING
-       copyFoldingState(curwin, wp);
-#endif
+       /* make the contents of the new window the same as the current one */
+       win_init(wp, curwin);
     }
 
     /*
@@ -1099,6 +1053,66 @@ win_split_ins(size, flags, newwin, dir)
     return OK;
 }
 
+/*
+ * Initialize window "newp" from window "oldp".
+ * Used when splitting a window and when creating a new tab page.
+ * The windows will both edit the same buffer.
+ */
+    static void
+win_init(newp, oldp)
+    win_T      *newp;
+    win_T      *oldp;
+{
+    int                i;
+
+    newp->w_buffer = oldp->w_buffer;
+    oldp->w_buffer->b_nwindows++;
+    newp->w_cursor = oldp->w_cursor;
+    newp->w_valid = 0;
+    newp->w_curswant = oldp->w_curswant;
+    newp->w_set_curswant = oldp->w_set_curswant;
+    newp->w_topline = oldp->w_topline;
+#ifdef FEAT_DIFF
+    newp->w_topfill = oldp->w_topfill;
+#endif
+    newp->w_leftcol = oldp->w_leftcol;
+    newp->w_pcmark = oldp->w_pcmark;
+    newp->w_prev_pcmark = oldp->w_prev_pcmark;
+    newp->w_alt_fnum = oldp->w_alt_fnum;
+    newp->w_fraction = oldp->w_fraction;
+    newp->w_prev_fraction_row = oldp->w_prev_fraction_row;
+#ifdef FEAT_JUMPLIST
+    copy_jumplist(oldp, newp);
+#endif
+#ifdef FEAT_QUICKFIX
+    copy_loclist(oldp, newp);
+#endif
+    if (oldp->w_localdir != NULL)
+       newp->w_localdir = vim_strsave(oldp->w_localdir);
+
+    /* Use the same argument list. */
+    newp->w_alist = oldp->w_alist;
+    ++newp->w_alist->al_refcount;
+    newp->w_arg_idx = oldp->w_arg_idx;
+
+    /*
+     * copy tagstack and options from existing window
+     */
+    for (i = 0; i < oldp->w_tagstacklen; i++)
+    {
+       newp->w_tagstack[i] = oldp->w_tagstack[i];
+       if (newp->w_tagstack[i].tagname != NULL)
+           newp->w_tagstack[i].tagname =
+                                  vim_strsave(newp->w_tagstack[i].tagname);
+    }
+    newp->w_tagstackidx = oldp->w_tagstackidx;
+    newp->w_tagstacklen = oldp->w_tagstacklen;
+    win_copy_options(oldp, newp);
+# ifdef FEAT_FOLDING
+    copyFoldingState(oldp, newp);
+# endif
+}
+
 #endif /* FEAT_WINDOWS */
 
 #if defined(FEAT_WINDOWS) || defined(PROTO)
@@ -1886,7 +1900,7 @@ win_close(win, free_buf)
     if (win->w_buffer->b_help)
        help_window = TRUE;
     else
-       clear_snapshot();
+       clear_snapshot(curtab);
 
 #ifdef FEAT_AUTOCMD
     if (win == curwin)
@@ -2813,35 +2827,33 @@ close_others(message, forceit)
 #endif /* FEAT_WINDOWS */
 
 /*
- * init the cursor in the window
- *
- * called when a new file is being edited
+ * Init the current window "curwin".
+ * Called when a new file is being edited.
  */
     void
-win_init(wp)
-    win_T      *wp;
+curwin_init()
 {
-    redraw_win_later(wp, NOT_VALID);
-    wp->w_lines_valid = 0;
-    wp->w_cursor.lnum = 1;
-    wp->w_curswant = wp->w_cursor.col = 0;
+    redraw_win_later(curwin, NOT_VALID);
+    curwin->w_lines_valid = 0;
+    curwin->w_cursor.lnum = 1;
+    curwin->w_curswant = curwin->w_cursor.col = 0;
 #ifdef FEAT_VIRTUALEDIT
-    wp->w_cursor.coladd = 0;
+    curwin->w_cursor.coladd = 0;
 #endif
-    wp->w_pcmark.lnum = 1;     /* pcmark not cleared but set to line 1 */
-    wp->w_pcmark.col = 0;
-    wp->w_prev_pcmark.lnum = 0;
-    wp->w_prev_pcmark.col = 0;
-    wp->w_topline = 1;
+    curwin->w_pcmark.lnum = 1; /* pcmark not cleared but set to line 1 */
+    curwin->w_pcmark.col = 0;
+    curwin->w_prev_pcmark.lnum = 0;
+    curwin->w_prev_pcmark.col = 0;
+    curwin->w_topline = 1;
 #ifdef FEAT_DIFF
-    wp->w_topfill = 0;
+    curwin->w_topfill = 0;
 #endif
-    wp->w_botline = 2;
+    curwin->w_botline = 2;
 #ifdef FEAT_FKMAP
     if (curwin->w_p_rl)
-       wp->w_farsi = W_CONV + W_R_L;
+       curwin->w_farsi = W_CONV + W_R_L;
     else
-       wp->w_farsi = W_CONV;
+       curwin->w_farsi = W_CONV;
 #endif
 }
 
@@ -2853,7 +2865,7 @@ win_init(wp)
     int
 win_alloc_first()
 {
-    if (win_alloc_firstwin() == FAIL)
+    if (win_alloc_firstwin(NULL) == FAIL)
        return FAIL;
 
 #ifdef FEAT_WINDOWS
@@ -2867,23 +2879,43 @@ win_alloc_first()
 }
 
 /*
- * Allocate one window and put an empty buffer in it.
- * Called to create the first window in a new tab page.
+ * Allocate the first window or the first window in a new tab page.
+ * When "oldwin" is NULL create an empty buffer for it.
+ * When "oldwin" is not NULL copy info from it to the new window (only with
+ * FEAT_WINDOWS).
  * Return FAIL when something goes wrong (out of memory).
  */
     static int
-win_alloc_firstwin()
+win_alloc_firstwin(oldwin)
+    win_T      *oldwin;
 {
     curwin = win_alloc(NULL);
-    curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
-    if (curwin == NULL || curbuf == NULL)
-       return FAIL;
-    curwin->w_buffer = curbuf;
-    curbuf->b_nwindows = 1;    /* there is one window */
+    if (oldwin == NULL)
+    {
+       /* Very first window, need to create an empty buffer for it and
+        * initialize from scratch. */
+       curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
+       if (curwin == NULL || curbuf == NULL)
+           return FAIL;
+       curwin->w_buffer = curbuf;
+       curbuf->b_nwindows = 1; /* there is one window */
 #ifdef FEAT_WINDOWS
-    curwin->w_alist = &global_alist;
+       curwin->w_alist = &global_alist;
+#endif
+       curwin_init();          /* init current window */
+    }
+#ifdef FEAT_WINDOWS
+    else
+    {
+       /* First window in new tab page, initialize it from "oldwin". */
+       win_init(curwin, oldwin);
+
+# ifdef FEAT_SCROLLBIND
+       /* We don't want scroll-binding in the first window. */
+       curwin->w_p_scb = FALSE;
+# endif
+    }
 #endif
-    win_init(curwin);          /* init current window */
 
     topframe = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
     if (topframe == NULL)
@@ -2944,11 +2976,13 @@ free_tabpage(tp)
 # ifdef FEAT_DIFF
     diff_clear(tp);
 # endif
+    clear_snapshot(tp);
     vim_free(tp);
 }
 
 /*
- * Create a new Tab page with one empty window.
+ * Create a new Tab page with one window.
+ * It will edit the current buffer, like after ":split".
  * Put it just after the current Tab page.
  * Return FAIL or OK.
  */
@@ -2963,7 +2997,7 @@ win_new_tabpage()
        return FAIL;
 
     /* Remember the current windows in this Tab page. */
-    if (leave_tabpage(NULL) == FAIL)
+    if (leave_tabpage(curbuf) == FAIL)
     {
        vim_free(newtp);
        return FAIL;
@@ -2971,11 +3005,8 @@ win_new_tabpage()
     curtab = newtp;
 
     /* Create a new empty window. */
-    if (win_alloc_firstwin() == OK)
+    if (win_alloc_firstwin(tp->tp_curwin) == OK)
     {
-       /* copy options from previous to new curwin */
-       win_copy_options(tp->tp_curwin, curwin);
-
        /* Make the new Tab page the new topframe. */
        newtp->tp_next = tp->tp_next;
        tp->tp_next = newtp;
@@ -2985,6 +3016,10 @@ win_new_tabpage()
        newtp->tp_topframe = topframe;
        last_status(FALSE);
        redraw_all_later(CLEAR);
+#ifdef FEAT_AUTOCMD
+       apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
+       apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
+#endif
        return OK;
     }
 
@@ -3082,7 +3117,7 @@ leave_tabpage(new_curbuf)
     apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
     if (curtab != tp)
        return FAIL;
-    apply_autocmds(EVENT_TABLEAVEPRE, NULL, NULL, FALSE, curbuf);
+    apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf);
     if (curtab != tp)
        return FAIL;
 #endif
@@ -3104,6 +3139,7 @@ leave_tabpage(new_curbuf)
 
 /*
  * Start using tab page "tp".
+ * Only to be used after leave_tabpage() or freeing the current tab page.
  */
 /*ARGSUSED*/
     static void
@@ -3117,12 +3153,14 @@ enter_tabpage(tp, old_curbuf)
     firstwin = tp->tp_firstwin;
     lastwin = tp->tp_lastwin;
     topframe = tp->tp_topframe;
+#ifdef FEAT_AUTOCMD
+    apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
+#endif
+
     win_enter_ext(tp->tp_curwin, FALSE, TRUE);
     prevwin = tp->tp_prevwin;
 
 #ifdef FEAT_AUTOCMD
-    apply_autocmds(EVENT_TABENTERPOST, NULL, NULL, FALSE, curbuf);
-    apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
     if (old_curbuf != curbuf)
        apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
 #endif
@@ -3169,6 +3207,14 @@ goto_tabpage(n)
     tabpage_T  *tp;
     int                i;
 
+    /* If there is only one it can't work. */
+    if (first_tabpage->tp_next == NULL)
+    {
+       if (n > 1)
+           beep_flush();
+       return;
+    }
+
     if (n == 0)
     {
        /* No count, go to next tab page, wrap around end. */
@@ -5018,7 +5064,7 @@ last_status_rec(fr, statusline)
     int
 tabpageline_height()
 {
-    switch (p_tal)
+    switch (p_stal)
     {
        case 0: return 0;
        case 1: return (first_tabpage->tp_next == NULL) ? 0 : 1;
@@ -5419,7 +5465,6 @@ check_lnums(do_curwin)
  * fr_child
  * fr_win (only valid for the old curwin, NULL otherwise)
  */
-static frame_T *snapshot = NULL;
 
 /*
  * Create a snapshot of the current frame sizes.
@@ -5427,8 +5472,8 @@ static frame_T *snapshot = NULL;
     static void
 make_snapshot()
 {
-    clear_snapshot();
-    make_snapshot_rec(topframe, &snapshot);
+    clear_snapshot(curtab);
+    make_snapshot_rec(topframe, &curtab->tp_snapshot);
 }
 
     static void
@@ -5456,10 +5501,11 @@ make_snapshot_rec(fr, frp)
  * Remove any existing snapshot.
  */
     static void
-clear_snapshot()
+clear_snapshot(tp)
+    tabpage_T  *tp;
 {
-    clear_snapshot_rec(snapshot);
-    snapshot = NULL;
+    clear_snapshot_rec(tp->tp_snapshot);
+    tp->tp_snapshot = NULL;
 }
 
     static void
@@ -5485,20 +5531,20 @@ restore_snapshot(close_curwin)
 {
     win_T      *wp;
 
-    if (snapshot != NULL
+    if (curtab->tp_snapshot != NULL
 # ifdef FEAT_VERTSPLIT
-           && snapshot->fr_width == topframe->fr_width
+           && curtab->tp_snapshot->fr_width == topframe->fr_width
 # endif
-           && snapshot->fr_height == topframe->fr_height
-           && check_snapshot_rec(snapshot, topframe) == OK)
+           && curtab->tp_snapshot->fr_height == topframe->fr_height
+           && check_snapshot_rec(curtab->tp_snapshot, topframe) == OK)
     {
-       wp = restore_snapshot_rec(snapshot, topframe);
+       wp = restore_snapshot_rec(curtab->tp_snapshot, topframe);
        win_comp_pos();
        if (wp != NULL && close_curwin)
            win_goto(wp);
        redraw_all_later(CLEAR);
     }
-    clear_snapshot();
+    clear_snapshot(curtab);
 }
 
 /*