From 33f4adf0726a7ccf172cb6e038a3422c1e659855 Mon Sep 17 00:00:00 2001 From: hluk Date: Fri, 19 Apr 2013 22:07:06 +0200 Subject: [PATCH] FakeVim: Keep undo/redo integrity while the plugin is disabled Change-Id: If17252ecfd7adc6bbe518ce97908f1f8fb2772f1 Reviewed-by: hjk --- src/plugins/fakevim/fakevimhandler.cpp | 41 +++++++++++++++++++------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 30d2533a4d4..64c24d7de90 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -1794,6 +1794,7 @@ public: QStack m_undo; QStack m_redo; State m_undoState; + int m_lastUndoSteps; // extra data for '.' void replay(const QString &text); @@ -1957,6 +1958,7 @@ FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget) if (editor()) { connect(EDITOR(document()), SIGNAL(contentsChanged()), SLOT(onContentsChanged())); connect(EDITOR(document()), SIGNAL(undoCommandAdded()), SLOT(onUndoCommandAdded())); + m_lastUndoSteps = document()->availableUndoSteps(); } //new Highlighter(document(), &pythonRules); init(); @@ -2375,10 +2377,7 @@ void FakeVimHandler::Private::restoreWidget(int tabSize) EDITOR(setTabStopWidth(charWidth * tabSize)); m_visualMode = NoVisualMode; // Force "ordinary" cursor. - m_mode = InsertMode; - m_submode = NoSubMode; - m_subsubmode = NoSubSubMode; - updateCursorShape(); + EDITOR(setOverwriteMode(false)); updateSelection(); updateHighlights(); } @@ -7090,17 +7089,37 @@ void FakeVimHandler::Private::onContentsChanged() { if (!document()->isUndoAvailable()) m_undo.clear(); - else if (m_editBlockLevel == 0 && !m_undo.isEmpty() && !isInsertMode()) - m_undo.push(State()); // Save undo state for external change. + + const int undoSteps = document()->availableUndoSteps(); + + if (m_editBlockLevel == 0) { + // Break undo/redo stacks on external undo/redo. + if (m_lastUndoSteps > undoSteps && !m_undo.isEmpty()) { + if ((--m_undo.top().revisions) <= 0) + m_undo.pop(); + m_redo.push(State()); + } else if (m_lastUndoSteps < undoSteps && !m_redo.isEmpty()) { + if ((--m_redo.top().revisions) <= 0) + m_redo.pop(); + m_undo.push(State()); + } + } + + m_lastUndoSteps = undoSteps; } void FakeVimHandler::Private::onUndoCommandAdded() { m_redo.clear(); - if (m_editBlockLevel == 0 && !m_undo.isEmpty() && isInsertMode()) - ++m_undo.top().revisions; - else - ++m_undoState.revisions; + // Remember chage so it can be correctly undone/redone with undo/redo commands. + if (m_editBlockLevel == 0 && !m_undo.isEmpty()) { + if (isInsertMode()) + ++m_undo.top().revisions; // External change in insert mode (auto-completion etc.) + else + m_undo.push(State()); // External change while FakeVim disabled. + } else if (m_editBlockLevel > 0) { + ++m_undoState.revisions; // Document revision increased in our edit block. + } } char FakeVimHandler::Private::currentModeCode() const @@ -7164,11 +7183,11 @@ void FakeVimHandler::Private::undoRedo(bool undo) setMark(QLatin1Char('`'), lastPos); setCursorPosition(m_lastChangePosition); setAnchor(); - stack2.push(state); } else { updateFirstVisibleLine(); m_cursor = EDITOR(textCursor()); } + stack2.push(state); setTargetColumn(); if (atEndOfLine())