]> granicus.if.org Git - vim/commitdiff
Apply patch 7.2.445.
authorBram Moolenaar <Bram@vim.org>
Wed, 7 Jul 2010 16:26:28 +0000 (18:26 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 7 Jul 2010 16:26:28 +0000 (18:26 +0200)
src/misc1.c
src/undo.c

index 3f8a0442a991db5f730b3d6a1f95d586f85691c0..24b8521c6c82182bf3344996e23b0138728105a0 100644 (file)
@@ -2467,10 +2467,12 @@ skip_to_option_part(p)
 }
 
 /*
- * changed() is called when something in the current buffer is changed.
+ * Call this function when something in the current buffer is changed.
  *
  * Most often called through changed_bytes() and changed_lines(), which also
  * mark the area of the display to be redrawn.
+ *
+ * Careful: may trigger autocommands that reload the buffer.
  */
     void
 changed()
@@ -2545,6 +2547,7 @@ static void changed_common __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume, l
  * - marks the windows on this buffer to be redisplayed
  * - marks the buffer changed by calling changed()
  * - invalidates cached values
+ * Careful: may trigger autocommands that reload the buffer.
  */
     void
 changed_bytes(lnum, col)
@@ -2658,6 +2661,7 @@ deleted_lines_mark(lnum, count)
  * below the changed lines (BEFORE the change).
  * When only inserting lines, "lnum" and "lnume" are equal.
  * Takes care of calling changed() and updating b_mod_*.
+ * Careful: may trigger autocommands that reload the buffer.
  */
     void
 changed_lines(lnum, col, lnume, xtra)
@@ -2725,6 +2729,11 @@ changed_lines_buf(buf, lnum, lnume, xtra)
     }
 }
 
+/*
+ * Common code for when a change is was made.
+ * See changed_lines() for the arguments.
+ * Careful: may trigger autocommands that reload the buffer.
+ */
     static void
 changed_common(lnum, col, lnume, xtra)
     linenr_T   lnum;
@@ -2975,6 +2984,7 @@ check_status(buf)
  * Don't use emsg(), because it flushes the macro buffer.
  * If we have undone all changes b_changed will be FALSE, but "b_did_warn"
  * will be TRUE.
+ * Careful: may trigger autocommands that reload the buffer.
  */
     void
 change_warning(col)
index 497fc6b50d0f2564d3600e57a8368306ebbed086..86b4d81d409092da3e52b41456ee7c0b757888ab 100644 (file)
@@ -196,7 +196,7 @@ u_check_tree(u_header_T *uhp,
     }
 }
 
-    void
+    static void
 u_check(int newhead_may_be_NULL)
 {
     seen_b_u_newhead = 0;
@@ -331,6 +331,9 @@ undo_allowed()
     return TRUE;
 }
 
+/*
+ * Common code for various ways to save text before a change.
+ */
     static int
 u_savecommon(top, bot, newbot)
     linenr_T   top, bot;
@@ -385,7 +388,7 @@ u_savecommon(top, bot, newbot)
     size = bot - top - 1;
 
     /*
-     * if curbuf->b_u_synced == TRUE make a new header
+     * If curbuf->b_u_synced == TRUE make a new header.
      */
     if (curbuf->b_u_synced)
     {
@@ -1938,6 +1941,12 @@ u_doit(startcount)
        u_oldcount = -1;
     while (count--)
     {
+       /* Do the change warning now, so that it triggers FileChangedRO when
+        * needed.  This may cause the file to be reloaded, that must happen
+        * before we do anything, because it may change curbuf->b_u_curhead
+        * and more. */
+       change_warning(0);
+
        if (undo_undoes)
        {
            if (curbuf->b_u_curhead == NULL)            /* first undo */
@@ -2230,8 +2239,11 @@ undo_time(step, sec, file, absolute)
        /*
         * First go up the tree as much as needed.
         */
-       for (;;)
+       while (!got_int)
        {
+           /* Do the change warning now, for the same reason as above. */
+           change_warning(0);
+
            uhp = curbuf->b_u_curhead;
            if (uhp == NULL)
                uhp = curbuf->b_u_newhead;
@@ -2248,9 +2260,15 @@ undo_time(step, sec, file, absolute)
        /*
         * And now go down the tree (redo), branching off where needed.
         */
-       uhp = curbuf->b_u_curhead;
-       while (uhp != NULL)
+       while (!got_int)
        {
+           /* Do the change warning now, for the same reason as above. */
+           change_warning(0);
+
+           uhp = curbuf->b_u_curhead;
+           if (uhp == NULL)
+               break;
+
            /* Go back to the first branch with a mark. */
            while (uhp->uh_alt_prev.ptr != NULL
                                     && uhp->uh_alt_prev.ptr->uh_walk == mark)
@@ -2349,6 +2367,12 @@ u_undoredo(undo)
     int                empty_buffer;               /* buffer became empty */
     u_header_T *curhead = curbuf->b_u_curhead;
 
+#ifdef FEAT_AUTOCMD
+    /* Don't want autocommands using the undo structures here, they are
+     * invalid till the end. */
+    block_autocmds();
+#endif
+
 #ifdef U_DEBUG
     u_check(FALSE);
 #endif
@@ -2378,6 +2402,9 @@ u_undoredo(undo)
        if (top > curbuf->b_ml.ml_line_count || top >= bot
                                      || bot > curbuf->b_ml.ml_line_count + 1)
        {
+#ifdef FEAT_AUTOCMD
+           unblock_autocmds();
+#endif
            EMSG(_("E438: u_undo: line numbers wrong"));
            changed();          /* don't want UNCHANGED now */
            return;
@@ -2592,6 +2619,10 @@ u_undoredo(undo)
     /* The timestamp can be the same for multiple changes, just use the one of
      * the undone/redone change. */
     curbuf->b_u_time_cur = curhead->uh_time;
+
+#ifdef FEAT_AUTOCMD
+    unblock_autocmds();
+#endif
 #ifdef U_DEBUG
     u_check(FALSE);
 #endif