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
This commit is contained in:
Martin Aumueller
2009-02-09 08:45:02 +01:00
parent 137ba736a7
commit bf3c4a1562

View File

@@ -312,6 +312,7 @@ public:
QStack<EditOperation> m_undoStack;
QStack<EditOperation> m_redoStack;
QStack<int> m_undoGroupStack;
QMap<int, int> 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()