From 29eff525295fd98697a6682cea648b14a83959cd Mon Sep 17 00:00:00 2001 From: hjk <qthjk@ovi.com> Date: Tue, 27 Dec 2011 17:39:56 +0100 Subject: [PATCH] fakevim: rework undo/redo cursor positioning Change-Id: I1daa788377295fb1446f31d9a74b9fd0df6920d1 Reviewed-by: hjk <qthjk@ovi.com> --- src/plugins/fakevim/fakevimhandler.cpp | 106 ++++++++++++++----------- 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 0bd773c3042..33f2e25e46d 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -862,8 +862,6 @@ public: { return document()->characterAt(position()); } void beginEditBlock() { UNDO_DEBUG("BEGIN EDIT BLOCK"); cursor().beginEditBlock(); } - void beginEditBlock(int pos) - { setUndoPosition(pos); cursor().beginEditBlock(); } void endEditBlock() { UNDO_DEBUG("END EDIT BLOCK"); cursor().endEditBlock(); } void joinPreviousEditBlock() @@ -982,7 +980,7 @@ public: // undo handling void undo(); void redo(); - void setUndoPosition(int pos); + void setUndoPosition(); QMap<int, int> m_undoCursorPosition; // revision -> position // extra data for '.' @@ -1433,7 +1431,6 @@ EventResult FakeVimHandler::Private::handleKey(const Input &input) EventResult FakeVimHandler::Private::handleKey2() { - setUndoPosition(position()); if (m_mode == InsertMode) { EventResult result = EventUnhandled; foreach (const Input &in, g.pendingInput) { @@ -1484,9 +1481,13 @@ void FakeVimHandler::Private::stopIncrementalFind() } } -void FakeVimHandler::Private::setUndoPosition(int pos) +void FakeVimHandler::Private::setUndoPosition() { - m_undoCursorPosition[document()->availableUndoSteps()] = pos; + int pos = qMin(position(), anchor()); + if (m_visualMode == VisualLineMode) + pos = firstPositionInLine(lineForPosition(pos)); + const int rev = document()->availableUndoSteps(); + m_undoCursorPosition[rev] = pos; } void FakeVimHandler::Private::moveDown(int n) @@ -1607,7 +1608,6 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) if (m_movetype == MoveLineWise) insertAutomaticIndentation(true); endEditBlock(); - setUndoPosition(position()); enterInsertMode(); m_submode = NoSubMode; } else if (m_submode == DeleteSubMode) { @@ -1656,16 +1656,17 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) handleStartOfLine(); endEditBlock(); } else if (m_submode == IndentSubMode) { + setUndoPosition(); recordJump(); - beginEditBlock(); indentSelectedText(); - endEditBlock(); m_submode = NoSubMode; } else if (m_submode == ShiftRightSubMode) { + setUndoPosition(); recordJump(); shiftRegionRight(1); m_submode = NoSubMode; } else if (m_submode == ShiftLeftSubMode) { + setUndoPosition(); recordJump(); shiftRegionLeft(1); m_submode = NoSubMode; @@ -1926,6 +1927,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) m_rangemode = RangeLineMode; } else if (m_submode == ReplaceSubMode) { if (isVisualMode()) { + setUndoPosition(); m_lastChangePosition = position(); if (isVisualLineMode()) m_rangemode = RangeLineMode; @@ -1940,6 +1942,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) transformText(range, tr, input.asChar()); setPosition(range.beginPos); } else if (count() <= rightDist()) { + setUndoPosition(); m_lastChangePosition = position(); setAnchor(); moveRight(count()); @@ -1959,6 +1962,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) m_submode = NoSubMode; finishMovement(); } else if (m_submode == ChangeSubMode && input.is('c')) { // tested + setUndoPosition(); m_lastChangePosition = position(); moveToStartOfLine(); setAnchor(); @@ -1969,6 +1973,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) setDotCommand("%1cc", count()); finishMovement(); } else if (m_submode == DeleteSubMode && input.is('d')) { // tested + setUndoPosition(); m_lastChangePosition = position(); m_movetype = MoveLineWise; int endPos = firstPositionInLine(lineForPosition(position()) + count() - 1); @@ -2198,29 +2203,36 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) replay(savedCommand, count()); enterCommandMode(); g.dotCommand = savedCommand; - } else if (input.is('<') && isNoVisualMode()) { - m_submode = ShiftLeftSubMode; - } else if (input.is('<') && isVisualMode()) { - shiftRegionLeft(1); - leaveVisualMode(); - } else if (input.is('>') && isNoVisualMode()) { - m_submode = ShiftRightSubMode; - } else if (input.is('>') && isVisualMode()) { - shiftRegionRight(1); - leaveVisualMode(); - } else if (input.is('=') && isNoVisualMode()) { - m_submode = IndentSubMode; - } else if (input.is('=') && isVisualMode()) { - beginEditBlock(); - indentSelectedText(); - endEditBlock(); - leaveVisualMode(); + } else if (input.is('<')) { + setUndoPosition(); + if (isNoVisualMode()) { + m_submode = ShiftLeftSubMode; + } else { + shiftRegionLeft(1); + leaveVisualMode(); + } + } else if (input.is('>')) { + setUndoPosition(); + if (isNoVisualMode()) { + m_submode = ShiftRightSubMode; + } else { + shiftRegionRight(1); + leaveVisualMode(); + } + } else if (input.is('=')) { + setUndoPosition(); + if (isNoVisualMode()) { + m_submode = IndentSubMode; + } else { + indentSelectedText(); + leaveVisualMode(); + } } else if (input.is('%')) { moveToMatchingParanthesis(); finishMovement(); } else if ((!isVisualMode() && input.is('a')) || (isVisualMode() && input.is('A'))) { leaveVisualMode(); - setUndoPosition(position()); + setUndoPosition(); breakEditBlock(); enterInsertMode(); m_lastInsertion.clear(); @@ -2228,7 +2240,7 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) moveRight(); updateMiniBuffer(); } else if (input.is('A')) { - setUndoPosition(position()); + setUndoPosition(); breakEditBlock(); moveBehindEndOfLine(); setAnchor(); @@ -2249,6 +2261,7 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) setTargetColumn(); finishMovement(); } else if (input.is('c') && isNoVisualMode()) { + setUndoPosition(); if (atEndOfLine()) moveLeft(); setAnchor(); @@ -2399,7 +2412,7 @@ EventResult FakeVimHandler::Private::handleCommandMode1(const Input &input) finishMovement(); } else if (!isVisualMode() && (input.is('i') || input.isKey(Key_Insert))) { setDotCommand(QString(QLatin1Char('i'))); // setDotCommand("%1i", count()); - setUndoPosition(position()); + setUndoPosition(); breakEditBlock(); enterInsertMode(); updateMiniBuffer(); @@ -2416,6 +2429,7 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) EventResult handled = EventHandled; if (input.is('I')) { + setUndoPosition(); setDotCommand(QString(QLatin1Char('I'))); // setDotCommand("%1I", count()); if (isVisualMode()) { int beginLine = lineForPosition(anchor()); @@ -2430,7 +2444,6 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) m_gflag = false; //m_tc.clearSelection(); } - setUndoPosition(position()); breakEditBlock(); enterInsertMode(); } else if (input.isControl('i')) { @@ -2530,10 +2543,10 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) updateSelection(); } else if (input.is('o')) { setDotCommand("%1o", count()); - setUndoPosition(position()); + setUndoPosition(); breakEditBlock(); enterInsertMode(); - beginEditBlock(position()); + beginEditBlock(); moveToFirstNonBlankOnLine(); moveBehindEndOfLine(); insertText(QString("\n")); @@ -2541,10 +2554,10 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) endEditBlock(); } else if (input.is('O')) { setDotCommand("%1O", count()); - setUndoPosition(position()); + setUndoPosition(); breakEditBlock(); enterInsertMode(); - beginEditBlock(position()); + beginEditBlock(); moveToFirstNonBlankOnLine(); moveToStartOfLine(); insertText(QString("\n")); @@ -2563,15 +2576,17 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) setDotCommand("%1p", count()); finishMovement(); } else if (input.is('r')) { + setUndoPosition(); m_submode = ReplaceSubMode; } else if (!isVisualMode() && input.is('R')) { - setUndoPosition(position()); + setUndoPosition(); breakEditBlock(); enterReplaceMode(); updateMiniBuffer(); } else if (input.isControl('r')) { redo(); } else if (input.is('s') && isVisualBlockMode()) { + setUndoPosition(); Range range(position(), anchor(), RangeBlockMode); int beginLine = lineForPosition(anchor()); int endLine = lineForPosition(position()); @@ -2580,10 +2595,10 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) yankText(range, m_register); removeText(range); setDotCommand("%1s", count()); - setUndoPosition(position()); breakEditBlock(); enterInsertMode(); } else if (input.is('s')) { + setUndoPosition(); leaveVisualMode(); if (atEndOfLine()) moveLeft(); @@ -2594,10 +2609,10 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) setDotCommand("%1s", count()); m_opcount.clear(); m_mvcount.clear(); - setUndoPosition(position()); breakEditBlock(); enterInsertMode(); } else if (input.is('S')) { + setUndoPosition(); beginEditBlock(); if (!isVisualMode()) { const int line = cursorLine() + 1; @@ -2606,7 +2621,6 @@ EventResult FakeVimHandler::Private::handleCommandMode2(const Input &input) setAnchorAndPosition(anc, pos); } setDotCommand("%1S", count()); - setUndoPosition(position()); breakEditBlock(); enterInsertMode(); m_submode = ChangeSubMode; @@ -3625,7 +3639,7 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) if (endLine == -1) endLine = linesInDocument(); //qDebug() << "LINES: " << beginLine << endLine; - QString prefix = cmd.args; + //QString prefix = cmd.args; const bool forced = cmd.hasBang; //const bool quit = prefix.contains(QChar('q')) || prefix.contains(QChar('x')); //const bool quitAll = quit && prefix.contains(QChar('a')); @@ -3711,7 +3725,7 @@ bool FakeVimHandler::Private::handleExBangCommand(const ExCommand &cmd) // :! proc.closeWriteChannel(); proc.waitForFinished(); QString result = QString::fromUtf8(proc.readAllStandardOutput()); - beginEditBlock(targetPosition); + beginEditBlock(); removeText(currentRange()); insertText(result); setPosition(targetPosition); @@ -4052,6 +4066,7 @@ void FakeVimHandler::Private::moveToFirstNonBlankOnLine() void FakeVimHandler::Private::indentSelectedText(QChar typedChar) { + beginEditBlock(); setTargetColumn(); int beginLine = qMin(lineForPosition(position()), lineForPosition(anchor())); int endLine = qMax(lineForPosition(position()), lineForPosition(anchor())); @@ -4063,6 +4078,7 @@ void FakeVimHandler::Private::indentSelectedText(QChar typedChar) handleStartOfLine(); setTargetColumn(); setDotCommand("%1==", endLine - beginLine + 1); + endEditBlock(); } void FakeVimHandler::Private::indentText(const Range &range, QChar typedChar) @@ -4098,7 +4114,7 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat) targetPos = firstPositionInLine(beginLine); const int sw = config(ConfigShiftWidth).toInt(); - beginEditBlock(targetPos); + beginEditBlock(); for (int line = beginLine; line <= endLine; ++line) { QString data = lineContents(line); const Column col = indentation(data); @@ -4127,7 +4143,7 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat) if (hasConfig(ConfigStartOfLine)) targetPos = firstPositionInLine(beginLine); - beginEditBlock(targetPos); + beginEditBlock(); for (int line = endLine; line >= beginLine; --line) { int pos = firstPositionInLine(line); const QString text = lineContents(line); @@ -4479,7 +4495,7 @@ QString FakeVimHandler::Private::selectText(const Range &range) const int firstPos = firstPositionInLine(lineForPosition(range.beginPos)); int lastLine = lineForPosition(range.endPos); bool endOfDoc = lastLine == document()->lastBlock().blockNumber() + 1; - int lastPos = endOfDoc ? lastPositionInDocument() : firstPositionInLine(lastLine + 1); + int lastPos = endOfDoc ? lastPositionInDocument() : firstPositionInLine(lastLine + 1); tc.setPosition(firstPos, MoveAnchor); tc.setPosition(lastPos, KeepAnchor); return tc.selection().toPlainText() + QString((endOfDoc? "\n" : "")); @@ -4539,7 +4555,7 @@ void FakeVimHandler::Private::transformText(const Range &range, } case RangeLineMode: case RangeLineModeExclusive: { - beginEditBlock(range.beginPos); + beginEditBlock(); tc.setPosition(range.beginPos, MoveAnchor); tc.movePosition(StartOfLine, MoveAnchor); tc.setPosition(range.endPos, KeepAnchor); @@ -4579,7 +4595,7 @@ void FakeVimHandler::Private::transformText(const Range &range, if (range.rangemode == RangeBlockAndTailMode) endColumn = INT_MAX - 1; QTextBlock block = document()->findBlockByNumber(endLine - 1); - beginEditBlock(range.beginPos); + beginEditBlock(); for (int i = beginLine; i <= endLine && block.isValid(); ++i) { int bCol = qMin(beginColumn, block.length() - 1); int eCol = qMin(endColumn + 1, block.length() - 1); -- GitLab