commit ed3d9544a331a7c28730089e7b059eea592584c4
Author: Jean-Marc Lasgouttes <[email protected]>
Date:   Thu Mar 12 14:47:39 2015 +0100

    Improve undo of consecutive insertions/deletions
    
    The old scheme was:
     * multiple insertions are undone by groups of 20
     * multiple deletions are undone in one big block
    
    The new scheme is to stop merging undo elements after 2 seconds of elapsed 
time.
    
    Moreover, the merging of undo elements stops when the cursor has moved. 
Potentially, this could allow to remove many of the finishUndo() calls.
    
    Fixes bug #9204.

diff --git a/src/Text.cpp b/src/Text.cpp
index ea9fba7..c438f77 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -198,7 +198,7 @@ void mergeParagraph(BufferParams const & bparams,
 
 
 Text::Text(InsetText * owner, bool use_default_layout)
-       : owner_(owner), autoBreakRows_(false), undo_counter_(0)
+       : owner_(owner), autoBreakRows_(false)
 {
        pars_.push_back(Paragraph());
        Paragraph & par = pars_.back();
@@ -212,7 +212,7 @@ Text::Text(InsetText * owner, bool use_default_layout)
 
 
 Text::Text(InsetText * owner, Text const & text)
-       : owner_(owner), autoBreakRows_(text.autoBreakRows_), undo_counter_(0)
+       : owner_(owner), autoBreakRows_(text.autoBreakRows_)
 {
        pars_ = text.pars_;
        ParagraphList::iterator const end = pars_.end();
@@ -1081,15 +1081,6 @@ void Text::charInserted(Cursor & cur)
 {
        Paragraph & par = cur.paragraph();
 
-       // Here we call finishUndo for every 20 characters inserted.
-       // This is from my experience how emacs does it. (Lgb)
-       if (undo_counter_ < 20) {
-               ++undo_counter_;
-       } else {
-               cur.finishUndo();
-               undo_counter_ = 0;
-       }
-
        // register word if a non-letter was entered
        if (cur.pos() > 1
            && !par.isWordSeparator(cur.pos() - 2)
diff --git a/src/Text.h b/src/Text.h
index e6759ef..4c8ab94 100644
--- a/src/Text.h
+++ b/src/Text.h
@@ -382,8 +382,6 @@ private:
        bool autoBreakRows_;
        /// position of the text in the buffer.
        DocIterator macrocontext_position_;
-       ///
-       unsigned int undo_counter_;
 };
 
 
diff --git a/src/Undo.cpp b/src/Undo.cpp
index 2a01c8b..7a5b176 100644
--- a/src/Undo.cpp
+++ b/src/Undo.cpp
@@ -33,6 +33,7 @@
 #include "support/debug.h"
 #include "support/gettext.h"
 #include "support/lassert.h"
+#include "support/lyxtime.h"
 
 #include <algorithm>
 #include <deque>
@@ -72,7 +73,7 @@ struct UndoElement
                    bool lc, size_t gid) :
                kind(kin), cur_before(cb), cell(cel), from(fro), end(en),
                pars(pl), array(ar), bparams(0),
-               lyx_clean(lc), group_id(gid)
+               lyx_clean(lc), group_id(gid), time(current_time())
                {
                }
        ///
@@ -80,11 +81,11 @@ struct UndoElement
                                bool lc, size_t gid) :
                kind(ATOMIC_UNDO), cur_before(cb), cell(), from(0), end(0),
                pars(0), array(0), bparams(new BufferParams(bp)),
-               lyx_clean(lc), group_id(gid)
+               lyx_clean(lc), group_id(gid), time(current_time())
        {
        }
        ///
-       UndoElement(UndoElement const & ue)
+       UndoElement(UndoElement const & ue) : time(current_time())
        {
                kind = ue.kind;
                cur_before = ue.cur_before;
@@ -127,6 +128,8 @@ struct UndoElement
        bool lyx_clean;
        /// the element's group id
        size_t group_id;
+       /// timestamp
+       time_t time;
 private:
        /// Protect construction
        UndoElement();
@@ -325,9 +328,13 @@ void Undo::Private::doRecordUndo(UndoKind kind,
            && samePar(stack.top().cell, cell)
            && stack.top().kind == kind
            && stack.top().from == from
-           && stack.top().end == end) {
+           && stack.top().end == end
+           && stack.top().cur_after == cur_before
+           && current_time() - stack.top().time <= 2) {
                // reset cur_after; it will be filled correctly by endUndoGroup.
                stack.top().cur_after = CursorData();
+               // update the timestamp of the undo element
+               stack.top().time = current_time();
                return;
        }
 

Reply via email to