From bf3c4a15626ae50ea9258f505ef2b356a242f2bb Mon Sep 17 00:00:00 2001 From: Martin Aumueller Date: Mon, 9 Feb 2009 08:45:02 +0100 Subject: [PATCH] fakevim: use QTextDocument's undo/redo operations this has several advantages compared to an undo/redo stack private to fakevim: - change marks in document correspond to actual changes - mouse pasting does not invalidate the fakevim undo/redo stack - menu commands (such as undo/redo from the Edit menu) do not invalidate the fakevim undo/redo stack - possible other changes not caused by fakevim do not invalidate fakevim undo/redo stack it is pretty bad if the fakevim undo/redo stack becomes invalid, as applying these invalid undo/redo operations corrupts the document --- src/plugins/fakevim/fakevimhandler.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 11b4cc86cc3..52b8ffd4d33 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -312,6 +312,7 @@ public: QStack m_undoStack; QStack m_redoStack; QStack m_undoGroupStack; + QMap m_undoCursorPosition; // extra data for '.' QString m_dotCommand; @@ -416,7 +417,14 @@ bool FakeVimHandler::Private::handleEvent(QKeyEvent *ev) && (ev->modifiers() & Qt::ShiftModifier) == 0) { key += 32; } + + m_undoCursorPosition[EDITOR(document())->revision()] = m_tc.position(); + if (m_mode == InsertMode) + m_tc.joinPreviousEditBlock(); + else + m_tc.beginEditBlock(); bool handled = handleKey(key, um, ev->text()); + m_tc.endEditBlock(); // We fake vi-style end-of-line behaviour m_fakeEnd = (atEndOfLine() && m_mode == CommandMode); @@ -2012,6 +2020,11 @@ QWidget *FakeVimHandler::Private::editor() const void FakeVimHandler::Private::undo() { + EDITOR(undo()); + int rev = EDITOR(document())->revision(); + if (m_undoCursorPosition.contains(rev)) + m_tc.setPosition(m_undoCursorPosition[rev]); +#if 0 if (m_undoStack.isEmpty()) { showBlackMessage(tr("Already at oldest change")); } else { @@ -2033,10 +2046,22 @@ void FakeVimHandler::Private::undo() m_redoStack.push(op); showBlackMessage(QString()); } +#endif } void FakeVimHandler::Private::redo() { + int current = EDITOR(document())->revision(); + EDITOR(redo()); + int rev = EDITOR(document())->revision(); + if (rev == current) { + showBlackMessage(tr("Already at newest change")); + } else { + showBlackMessage(QString()); + if (m_undoCursorPosition.contains(rev)) + m_tc.setPosition(m_undoCursorPosition[rev]); + } +#if 0 if (m_redoStack.isEmpty()) { showBlackMessage(tr("Already at newest change")); } else { @@ -2058,6 +2083,7 @@ void FakeVimHandler::Private::redo() m_undoStack.push(op); showBlackMessage(QString()); } +#endif } void FakeVimHandler::Private::recordBeginGroup()