]> granicus.if.org Git - vim/commitdiff
Add the 'undoreload' option to be able to undo a file reload.
authorBram Moolenaar <Bram@vim.org>
Sat, 24 Jul 2010 18:27:03 +0000 (20:27 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 24 Jul 2010 18:27:03 +0000 (20:27 +0200)
16 files changed:
runtime/doc/options.txt
runtime/doc/tags
runtime/doc/todo.txt
runtime/doc/version7.txt
runtime/optwin.vim
src/buffer.c
src/ex_cmds.c
src/fileio.c
src/main.c
src/memline.c
src/option.c
src/option.h
src/proto/buffer.pro
src/proto/undo.pro
src/undo.c
src/vim.h

index 09e9ab352c9a45d9e547728474e6cc8b6fee5bbd..13932e0aa976f6713649cb8a2be3eef876f527fe 100644 (file)
@@ -7361,6 +7361,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        file on buffer read.
        The directory where the undo file is stored is specified by 'undodir'.
        For more information about this feature see |undo-persistence|.
+       The undo file is not read when 'undoreload' causes the buffer from
+       before a reload to be saved for undo.
        WARNING: this is a very new feature.  Use at your own risk!
 
                                                *'undolevels'* *'ul'*
@@ -7382,6 +7384,22 @@ A jump table for the options with a short description can be found at |Q_op|.
 <      This helps when you run out of memory for a single change.
        Also see |clear-undo|.
 
+                                               *'undoreload'* *'ur'*
+'undoreload' 'ur'      number  (default 10000)
+                       global
+                       {not in Vi}
+       Save the whole buffer for undo when reloading it.  This applies to the
+       ":e!" command and reloading for when the buffer changed outside of
+       Vim. |FileChangedShell|
+       The save only happens when this options is negative or when the number
+       of lines is smaller than the value of this option.
+       Set this option to zero to disable undo for a reload.
+
+       When saving undo for a reload, any undo file is not read.
+
+       Note that this causes the whole buffer to be stored in memory.  Set
+       this option to a lower value if you run out of memory.
+
                                                *'updatecount'* *'uc'*
 'updatecount' 'uc'     number  (default: 200)
                        global
index 45ee674c3274bf63465d94aac81163f4771eb9d7..78edec11e53a48668d15b8eafbaec259d286dd2f 100644 (file)
@@ -1029,8 +1029,10 @@ $VIMRUNTIME      starting.txt    /*$VIMRUNTIME*
 'undodir'      options.txt     /*'undodir'*
 'undofile'     options.txt     /*'undofile'*
 'undolevels'   options.txt     /*'undolevels'*
+'undoreload'   options.txt     /*'undoreload'*
 'updatecount'  options.txt     /*'updatecount'*
 'updatetime'   options.txt     /*'updatetime'*
+'ur'   options.txt     /*'ur'*
 'ut'   options.txt     /*'ut'*
 'vb'   options.txt     /*'vb'*
 'vbs'  options.txt     /*'vbs'*
@@ -6081,6 +6083,7 @@ hl-Directory      syntax.txt      /*hl-Directory*
 hl-ErrorMsg    syntax.txt      /*hl-ErrorMsg*
 hl-FoldColumn  syntax.txt      /*hl-FoldColumn*
 hl-Folded      syntax.txt      /*hl-Folded*
+hl-Ignore      syntax.txt      /*hl-Ignore*
 hl-IncSearch   syntax.txt      /*hl-IncSearch*
 hl-LineNr      syntax.txt      /*hl-LineNr*
 hl-MatchParen  syntax.txt      /*hl-MatchParen*
index acbacb5e6b47b54c05978a2d49b0d731f785865d..8327884dbfdfebef45210335263399705c520035 100644 (file)
@@ -40,9 +40,6 @@ Add documentation for Python 3 support.
     New patch 2010 Jul 24
     Docs patch by Dominique Pelle, Mar 25 included?
 
-'undoreload' option: when fewer lines than these consider a reload as a change
-action and save the text before the reload, don't clear undo info.
-
 Patch for :find completion. (Nazri Ramliy)
 But I prefer to keep term.h and include/term.h  He will work on it.
 
index 9fa0dabeab735ca9c6b067c91f6fd2f6ebe2bfa0..de2a7de1b8eeec657248d3b386fa2b54cc8d616c 100644 (file)
@@ -1,4 +1,4 @@
-*version7.txt*  For Vim version 7.3b.  Last change: 2010 Jul 20
+*version7.txt*  For Vim version 7.3b.  Last change: 2010 Jul 24
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -7171,6 +7171,9 @@ Added ":earlier 1f" and ":later 1f".
 Add file save counter to undo information.
 Added the |undotree()| and |undofile()| functions.
 
+Also added the 'undoreload' option.  This makes it possible to save the
+current text when reloading the buffer, so that it can be undone.
+
 
 More encryption                                        *new-more-encryption*
 ---------------
index c27fbd5d63da27a5095324262f462def87a53a8c..404cf8975126bb7f8d4610fcba8430f847aac623 100644 (file)
@@ -722,6 +722,8 @@ call <SID>OptionG("km", &km)
 call <SID>Header("editing text")
 call append("$", "undolevels\tmaximum number of changes that can be undone")
 call append("$", " \tset ul=" . &ul)
+call append("$", "undoreload\tmaximum number lines to save for undo on a buffer reload")
+call append("$", " \tset ur=" . &ur)
 call append("$", "modified\tchanges have been made and not written to a file")
 call append("$", "\t(local to buffer)")
 call <SID>BinOptionL("mod")
index a8808d396d3cb35c5136e04d807b2bc535d7606a..94e0b2e0b98e166aedccb0b8dfebbdfea3cf099e 100644 (file)
@@ -66,9 +66,10 @@ static void buf_delete_signs __ARGS((buf_T *buf));
  * Return FAIL for failure, OK otherwise.
  */
     int
-open_buffer(read_stdin, eap)
+open_buffer(read_stdin, eap, flags)
     int                read_stdin;         /* read file from stdin */
     exarg_T    *eap;               /* for forced 'ff' and 'fenc' or NULL */
+    int                flags;              /* extra flags for readfile() */
 {
     int                retval = OK;
 #ifdef FEAT_AUTOCMD
@@ -130,7 +131,8 @@ open_buffer(read_stdin, eap)
        netbeansFireChanges = 0;
 #endif
        retval = readfile(curbuf->b_ffname, curbuf->b_fname,
-                 (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, READ_NEW);
+                 (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+                 flags | READ_NEW);
 #ifdef FEAT_NETBEANS_INTG
        netbeansFireChanges = oldFire;
 #endif
@@ -151,13 +153,15 @@ open_buffer(read_stdin, eap)
         */
        curbuf->b_p_bin = TRUE;
        retval = readfile(NULL, NULL, (linenr_T)0,
-                 (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW + READ_STDIN);
+                 (linenr_T)0, (linenr_T)MAXLNUM, NULL,
+                 flags | (READ_NEW + READ_STDIN));
        curbuf->b_p_bin = save_bin;
        if (retval == OK)
        {
            line_count = curbuf->b_ml.ml_line_count;
            retval = readfile(NULL, NULL, (linenr_T)line_count,
-                           (linenr_T)0, (linenr_T)MAXLNUM, eap, READ_BUFFER);
+                           (linenr_T)0, (linenr_T)MAXLNUM, eap,
+                           flags | READ_BUFFER);
            if (retval == OK)
            {
                /* Delete the binary lines. */
@@ -412,7 +416,7 @@ close_buffer(win, buf, action)
     buf->b_nwindows = nwindows;
 #endif
 
-    buf_freeall(buf, del_buf, wipe_buf);
+    buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0));
 
 #ifdef FEAT_AUTOCMD
     /* Autocommands may have deleted the buffer. */
@@ -511,13 +515,15 @@ buf_clear_file(buf)
 
 /*
  * buf_freeall() - free all things allocated for a buffer that are related to
- * the file.
+ * the file.  flags:
+ * BFA_DEL       buffer is going to be deleted
+ * BFA_WIPE      buffer is going to be wiped out
+ * BFA_KEEP_UNDO  do not free undo information
  */
     void
-buf_freeall(buf, del_buf, wipe_buf)
+buf_freeall(buf, flags)
     buf_T      *buf;
-    int                del_buf UNUSED;     /* buffer is going to be deleted */
-    int                wipe_buf UNUSED;    /* buffer is going to be wiped out */
+    int                flags;
 {
 #ifdef FEAT_AUTOCMD
     int                is_curbuf = (buf == curbuf);
@@ -525,13 +531,13 @@ buf_freeall(buf, del_buf, wipe_buf)
     apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
     if (!buf_valid(buf))           /* autocommands may delete the buffer */
        return;
-    if (del_buf && buf->b_p_bl)
+    if ((flags & BFA_DEL) && buf->b_p_bl)
     {
        apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf);
        if (!buf_valid(buf))        /* autocommands may delete the buffer */
            return;
     }
-    if (wipe_buf)
+    if (flags & BFA_WIPE)
     {
        apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
                                                                  FALSE, buf);
@@ -576,10 +582,13 @@ buf_freeall(buf, del_buf, wipe_buf)
 #ifdef FEAT_TCL
     tcl_buffer_free(buf);
 #endif
-    u_blockfree(buf);              /* free the memory allocated for undo */
     ml_close(buf, TRUE);           /* close and delete the memline/memfile */
     buf->b_ml.ml_line_count = 0;    /* no lines in buffer */
-    u_clearall(buf);               /* reset all undo information */
+    if ((flags & BFA_KEEP_UNDO) == 0)
+    {
+       u_blockfree(buf);           /* free the memory allocated for undo */
+       u_clearall(buf);            /* reset all undo information */
+    }
 #ifdef FEAT_SYN_HL
     syntax_clear(&buf->b_s);       /* reset syntax info */
 #endif
@@ -1423,7 +1432,7 @@ enter_buffer(buf)
            did_filetype = FALSE;
 #endif
 
-       open_buffer(FALSE, NULL);
+       open_buffer(FALSE, NULL, 0);
     }
     else
     {
@@ -1625,7 +1634,7 @@ buflist_new(ffname, sfname, lnum, flags)
     if (buf == curbuf)
     {
        /* free all things allocated for this buffer */
-       buf_freeall(buf, FALSE, FALSE);
+       buf_freeall(buf, 0);
        if (buf != curbuf)       /* autocommands deleted the buffer! */
            return NULL;
 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
index 602c340da47a9c38578dbf6408576f57901d8682..20a39ffffac45bf8b3c4bc181d4858a021da1633 100644 (file)
@@ -3144,6 +3144,7 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
 #ifdef FEAT_SPELL
     int                did_get_winopts = FALSE;
 #endif
+    int                readfile_flags = 0;
 
     if (eap != NULL)
        command = eap->do_ecmd_cmd;
@@ -3570,7 +3571,22 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
        else
            new_name = NULL;
 #endif
-       buf_freeall(curbuf, FALSE, FALSE);   /* free all things for buffer */
+       if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur)
+       {
+           /* Save all the text, so that the reload can be undone.
+            * Sync first so that this is a separate undo-able action. */
+           u_sync(FALSE);
+           if (u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE)
+                                                                    == FAIL)
+               goto theend;
+           u_unchanged(curbuf);
+           buf_freeall(curbuf, BFA_KEEP_UNDO);
+
+           /* tell readfile() not to clear or reload undo info */
+           readfile_flags = READ_KEEP_UNDO;
+       }
+       else
+           buf_freeall(curbuf, 0);   /* free all things for buffer */
 #ifdef FEAT_AUTOCMD
        /* If autocommands deleted the buffer we were going to re-edit, give
         * up and jump to the end. */
@@ -3667,10 +3683,10 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
             * Open the buffer and read the file.
             */
 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
-           if (should_abort(open_buffer(FALSE, eap)))
+           if (should_abort(open_buffer(FALSE, eap, readfile_flags)))
                retval = FAIL;
 #else
-           (void)open_buffer(FALSE, eap);
+           (void)open_buffer(FALSE, eap, readfile_flags);
 #endif
 
 #if defined(HAS_SWAP_EXISTS_ACTION)
index aa3143efb3be211f2dcb3ae3f1cc3b8df253704c..1c0ac85806721a2fe3d5021de36f4d50bb2e0e97 100644 (file)
@@ -219,6 +219,7 @@ filemess(buf, name, s, attr)
  * READ_BUFFER read from curbuf instead of a file (converting after reading
  *             stdin)
  * READ_DUMMY  read into a dummy buffer (to check if file contents changed)
+ * READ_KEEP_UNDO  don't clear undo info or read it from a file
  *
  * return FAIL for failure, OK otherwise
  */
@@ -1195,8 +1196,12 @@ retry:
        conv_restlen = 0;
 #endif
 #ifdef FEAT_PERSISTENT_UNDO
-       read_undo_file = (newfile && curbuf->b_ffname != NULL && curbuf->b_p_udf
-                               && !filtering && !read_stdin && !read_buffer);
+       read_undo_file = (newfile && (flags & READ_KEEP_UNDO) == 0
+                                 && curbuf->b_ffname != NULL
+                                 && curbuf->b_p_udf
+                                 && !filtering
+                                 && !read_stdin
+                                 && !read_buffer);
        if (read_undo_file)
            sha256_start(&sha_ctx);
 #endif
@@ -7077,6 +7082,7 @@ buf_reload(buf, orig_mode)
     buf_T      *savebuf;
     int                saved = OK;
     aco_save_T aco;
+    int                flags = READ_NEW;
 
     /* set curwin/curbuf for "buf" and save some things */
     aucmd_prepbuf(&aco, buf);
@@ -7089,6 +7095,15 @@ buf_reload(buf, orig_mode)
        old_cursor = curwin->w_cursor;
        old_topline = curwin->w_topline;
 
+       if (saved == OK && (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur))
+       {
+           /* Save all the text, so that the reload can be undone.
+            * Sync first so that this is a separate undo-able action. */
+           u_sync(FALSE);
+           saved = u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE);
+           flags |= READ_KEEP_UNDO;
+       }
+
        /*
         * To behave like when a new file is edited (matters for
         * BufReadPost autocommands) we first need to delete the current
@@ -7096,7 +7111,7 @@ buf_reload(buf, orig_mode)
         * the old contents.  Can't use memory only, the file might be
         * too big.  Use a hidden buffer to move the buffer contents to.
         */
-       if (bufempty())
+       if (bufempty() || saved == FAIL)
            savebuf = NULL;
        else
        {
@@ -7128,7 +7143,7 @@ buf_reload(buf, orig_mode)
 #endif
            if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0,
                        (linenr_T)0,
-                       (linenr_T)MAXLNUM, &ea, READ_NEW) == FAIL)
+                       (linenr_T)MAXLNUM, &ea, flags) == FAIL)
            {
 #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
                if (!aborting())
@@ -7144,12 +7159,18 @@ buf_reload(buf, orig_mode)
                    (void)move_lines(savebuf, buf);
                }
            }
-           else if (buf == curbuf)
+           else if (buf == curbuf)  /* "buf" still valid */
            {
                /* Mark the buffer as unmodified and free undo info. */
                unchanged(buf, TRUE);
-               u_blockfree(buf);
-               u_clearall(buf);
+               if ((flags & READ_KEEP_UNDO) == 0)
+               {
+                   u_blockfree(buf);
+                   u_clearall(buf);
+               }
+               else
+                   /* Mark all undo states as changed. */
+                   u_unchanged(curbuf);
            }
        }
        vim_free(ea.cmd);
index d94b32a38a84a8e7810f5cb82d1bf130056b207e..4ccf3562865d2e22018aa24fed52f0dd1e287b24 100644 (file)
@@ -2470,7 +2470,7 @@ read_stdin()
     no_wait_return = TRUE;
     i = msg_didany;
     set_buflisted(TRUE);
-    (void)open_buffer(TRUE, NULL);     /* create memfile and read file */
+    (void)open_buffer(TRUE, NULL, 0);  /* create memfile and read file */
     no_wait_return = FALSE;
     msg_didany = i;
     TIME_MSG("reading stdin");
@@ -2591,7 +2591,9 @@ create_windows(parmp)
                swap_exists_action = SEA_DIALOG;
 #endif
                set_buflisted(TRUE);
-               (void)open_buffer(FALSE, NULL); /* create memfile, read file */
+
+               /* create memfile, read file */
+               (void)open_buffer(FALSE, NULL, 0);
 
 #if defined(HAS_SWAP_EXISTS_ACTION)
                if (swap_exists_action == SEA_QUIT)
index 0f7b1d11c7b9e7fe36ad0be8314c5e14eaa44bf2..9fe9439ae278e24ad49c074b2c786e69802ff7a5 100644 (file)
@@ -2529,7 +2529,7 @@ ml_append(lnum, line, len, newfile)
     int                newfile;        /* flag, see above */
 {
     /* When starting up, we might still need to create the memfile */
-    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL) == FAIL)
+    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
        return FAIL;
 
     if (curbuf->b_ml.ml_line_lnum != 0)
@@ -3078,7 +3078,7 @@ ml_replace(lnum, line, copy)
        return FAIL;
 
     /* When starting up, we might still need to create the memfile */
-    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL) == FAIL)
+    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
        return FAIL;
 
     if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */
index 8a3f6b59b6c98ad87e09b9c02dd90b3643a88dfd..2c5e88bfbdcbf16fa7b01fd40effcf92e46d92ab 100644 (file)
@@ -2655,6 +2655,9 @@ static struct vimoption
                            (char_u *)100L,
 #endif
                                (char_u *)0L} SCRIPTID_INIT},
+    {"undoreload",  "ur",   P_NUM|P_VI_DEF,
+                           (char_u *)&p_ur, PV_NONE,
+                           { (char_u *)10000L, (char_u *)0L} SCRIPTID_INIT},
     {"updatecount", "uc",   P_NUM|P_VI_DEF,
                            (char_u *)&p_uc, PV_NONE,
                            {(char_u *)200L, (char_u *)0L} SCRIPTID_INIT},
index 5e8574d828da411a139da53d9c40dfd1ef61a483..78560c697987303ce9fe503f704e8b823aa27c95 100644 (file)
@@ -826,6 +826,7 @@ static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm"
 #endif
 EXTERN char_u  *p_udir;        /* 'undodir' */
 EXTERN long    p_ul;           /* 'undolevels' */
+EXTERN long    p_ur;           /* 'undoreload' */
 EXTERN long    p_uc;           /* 'updatecount' */
 EXTERN long    p_ut;           /* 'updatetime' */
 #if defined(FEAT_WINDOWS) || defined(FEAT_FOLDING)
index a5fe42ff839bc2c133e8e705ca795afad8bb5218..df9c0b478a5bc6b1ce8d8b1f6488565911ef2b1f 100644 (file)
@@ -1,9 +1,9 @@
 /* buffer.c */
-int open_buffer __ARGS((int read_stdin, exarg_T *eap));
+int open_buffer __ARGS((int read_stdin, exarg_T *eap, int flags));
 int buf_valid __ARGS((buf_T *buf));
 void close_buffer __ARGS((win_T *win, buf_T *buf, int action));
 void buf_clear_file __ARGS((buf_T *buf));
-void buf_freeall __ARGS((buf_T *buf, int del_buf, int wipe_buf));
+void buf_freeall __ARGS((buf_T *buf, int flags));
 void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
 void handle_swap_exists __ARGS((buf_T *old_curbuf));
 char_u *do_bufdel __ARGS((int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit));
index a914c4925c6e7b168909218344e4ea11d80e2061..2cb149f42fb4c221ad389c79a99f2e4161df8e65 100644 (file)
@@ -5,6 +5,7 @@ int u_savesub __ARGS((linenr_T lnum));
 int u_inssub __ARGS((linenr_T lnum));
 int u_savedel __ARGS((linenr_T lnum, long nlines));
 int undo_allowed __ARGS((void));
+int u_savecommon __ARGS((linenr_T top, linenr_T bot, linenr_T newbot, int reload));
 void u_compute_hash __ARGS((char_u *hash));
 char_u *u_get_undo_file_name __ARGS((char_u *buf_ffname, int reading));
 void u_write_undo __ARGS((char_u *name, int forceit, buf_T *buf, char_u *hash));
index 58b55babbee371dc597be0ed32f6ef6d609f657d..6d50cc839eba97eb692d9d763586ead504c242ff 100644 (file)
@@ -90,7 +90,6 @@
 static void u_unch_branch __ARGS((u_header_T *uhp));
 static u_entry_T *u_get_headentry __ARGS((void));
 static void u_getbot __ARGS((void));
-static int u_savecommon __ARGS((linenr_T, linenr_T, linenr_T));
 static void u_doit __ARGS((int count));
 static void u_undoredo __ARGS((int undo));
 static void u_undo_end __ARGS((int did_undo, int absolute));
@@ -250,7 +249,7 @@ u_save(top, bot)
     if (top + 2 == bot)
        u_saveline((linenr_T)(top + 1));
 
-    return (u_savecommon(top, bot, (linenr_T)0));
+    return (u_savecommon(top, bot, (linenr_T)0, FALSE));
 }
 
 /*
@@ -266,7 +265,7 @@ u_savesub(lnum)
     if (undo_off)
        return OK;
 
-    return (u_savecommon(lnum - 1, lnum + 1, lnum + 1));
+    return (u_savecommon(lnum - 1, lnum + 1, lnum + 1, FALSE));
 }
 
 /*
@@ -282,7 +281,7 @@ u_inssub(lnum)
     if (undo_off)
        return OK;
 
-    return (u_savecommon(lnum - 1, lnum, lnum + 1));
+    return (u_savecommon(lnum - 1, lnum, lnum + 1, FALSE));
 }
 
 /*
@@ -301,7 +300,7 @@ u_savedel(lnum, nlines)
        return OK;
 
     return (u_savecommon(lnum - 1, lnum + nlines,
-                       nlines == curbuf->b_ml.ml_line_count ? 2 : lnum));
+                    nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, FALSE));
 }
 
 /*
@@ -342,13 +341,16 @@ undo_allowed()
  * Common code for various ways to save text before a change.
  * "top" is the line above the first changed line.
  * "bot" is the line below the last changed line.
+ * "newbot" is the new bottom line.  Use zero when not known.
+ * "reload" is TRUE when saving for a buffer reload.
  * Careful: may trigger autocommands that reload the buffer.
  * Returns FAIL when lines could not be saved, OK otherwise.
  */
-    static int
-u_savecommon(top, bot, newbot)
+    int
+u_savecommon(top, bot, newbot, reload)
     linenr_T   top, bot;
     linenr_T   newbot;
+    int                reload;
 {
     linenr_T   lnum;
     long       i;
@@ -358,49 +360,53 @@ u_savecommon(top, bot, newbot)
     u_entry_T  *prev_uep;
     long       size;
 
-    /* When making changes is not allowed return FAIL.  It's a crude way to
-     * make all change commands fail. */
-    if (!undo_allowed())
-       return FAIL;
+    if (!reload)
+    {
+       /* When making changes is not allowed return FAIL.  It's a crude way
+        * to make all change commands fail. */
+       if (!undo_allowed())
+           return FAIL;
 
-#ifdef U_DEBUG
-    u_check(FALSE);
-#endif
 #ifdef FEAT_NETBEANS_INTG
-    /*
-     * Netbeans defines areas that cannot be modified.  Bail out here when
-     * trying to change text in a guarded area.
-     */
-    if (netbeans_active())
-    {
-       if (netbeans_is_guarded(top, bot))
+       /*
+        * Netbeans defines areas that cannot be modified.  Bail out here when
+        * trying to change text in a guarded area.
+        */
+       if (netbeans_active())
        {
-           EMSG(_(e_guarded));
-           return FAIL;
+           if (netbeans_is_guarded(top, bot))
+           {
+               EMSG(_(e_guarded));
+               return FAIL;
+           }
+           if (curbuf->b_p_ro)
+           {
+               EMSG(_(e_nbreadonly));
+               return FAIL;
+           }
        }
-       if (curbuf->b_p_ro)
+#endif
+
+#ifdef FEAT_AUTOCMD
+       /*
+        * Saving text for undo means we are going to make a change.  Give a
+        * warning for a read-only file before making the change, so that the
+        * FileChangedRO event can replace the buffer with a read-write version
+        * (e.g., obtained from a source control system).
+        */
+       change_warning(0);
+       if (bot > curbuf->b_ml.ml_line_count + 1)
        {
-           EMSG(_(e_nbreadonly));
+           /* This happens when the FileChangedRO autocommand changes the
+            * file in a way it becomes shorter. */
+           EMSG(_("E834: Line count changed unexpectedly"));
            return FAIL;
        }
-    }
 #endif
-
-#ifdef FEAT_AUTOCMD
-    /*
-     * Saving text for undo means we are going to make a change.  Give a
-     * warning for a read-only file before making the change, so that the
-     * FileChangedRO event can replace the buffer with a read-write version
-     * (e.g., obtained from a source control system).
-     */
-    change_warning(0);
-    if (bot > curbuf->b_ml.ml_line_count + 1)
-    {
-       /* This happens when the FileChangedRO autocommand changes the file in
-        * a way it becomes shorter. */
-       EMSG(_("E834: Line count changed unexpectedly"));
-       return FAIL;
     }
+
+#ifdef U_DEBUG
+    u_check(FALSE);
 #endif
 
     size = bot - top - 1;
@@ -2905,7 +2911,7 @@ ex_undojoin(eap)
 }
 
 /*
- * Called after writing the file and setting b_changed to FALSE.
+ * Called after writing or reloading the file and setting b_changed to FALSE.
  * Now an undo means that the buffer is modified.
  */
     void
@@ -3197,7 +3203,7 @@ u_undoline()
 
     /* first save the line for the 'u' command */
     if (u_savecommon(curbuf->b_u_line_lnum - 1,
-                               curbuf->b_u_line_lnum + 1, (linenr_T)0) == FAIL)
+                      curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
        return;
     oldp = u_save_line(curbuf->b_u_line_lnum);
     if (oldp == NULL)
index ce55514387b3b714745d940e12897900b6c9ada0..6790a48c94a02b5eb36a574260abd5a7b115d868 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -953,6 +953,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
 #define READ_STDIN     0x04    /* read from stdin */
 #define READ_BUFFER    0x08    /* read from curbuf (converting stdin) */
 #define READ_DUMMY     0x10    /* reading into a dummy buffer */
+#define READ_KEEP_UNDO 0x20    /* keep undo info*/
 
 /* Values for change_indent() */
 #define INDENT_SET     1       /* set indent */
@@ -2174,4 +2175,9 @@ typedef int VimClipboard; /* This is required for the prototypes. */
 #define VIF_FORCEIT            4       /* overwrite info already read */
 #define VIF_GET_OLDFILES       8       /* load v:oldfiles */
 
+/* flags for buf_freeall() */
+#define BFA_DEL                1       /* buffer is going to be deleted */
+#define BFA_WIPE       2       /* buffer is going to be wiped out */
+#define BFA_KEEP_UNDO  4       /* do not free undo information */
+
 #endif /* VIM__H */