diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 2444135062dbfc31e8699262897b11f80b66f9e0..b9d2af0d69d6934f294966d56dbac30a6b8477da 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -160,7 +160,8 @@ enum SubMode WindowSubMode, // Used for Ctrl-w YankSubMode, // Used for y ZSubMode, // Used for z - CapitalZSubMode // Used for Z + CapitalZSubMode, // Used for Z + ReplaceSubMode, // Used for r }; /*! A \e SubSubMode is used for things that require one more data item @@ -176,7 +177,6 @@ enum SubSubMode InvertCaseSubSubMode, // Used for ~. DownCaseSubSubMode, // Used for gu. UpCaseSubSubMode, // Used for gU. - ReplaceSubSubMode, // Used for r after visual mode. TextObjectSubSubMode, // Used for thing like iw, aW, as etc. SearchSubSubMode, }; @@ -765,7 +765,6 @@ public: void downCase(const Range &range); void downCaseTransform(TransformationData *td); - QString m_replacement; void replaceText(const Range &range, const QString &str); void replaceTransform(TransformationData *td); @@ -1379,10 +1378,6 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand) downCase(currentRange()); if (!dotCommand.isEmpty()) setDotCommand("gu" + dotCommand); - } else if (m_subsubmode == ReplaceSubSubMode) { - replaceText(currentRange(), m_replacement); - if (!dotCommand.isEmpty()) - setDotCommand("r" + dotCommand); } m_submode = NoSubMode; m_subsubmode = NoSubSubMode; @@ -1635,26 +1630,6 @@ EventResult FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) selectQuotedStringTextObject(m_subsubdata.is('i'), input.key()); m_subsubmode = NoSubSubMode; finishMovement(); - } else if (m_submode == TransformSubMode && m_subsubmode == ReplaceSubSubMode) { - if (isVisualLineMode()) - m_rangemode = RangeLineMode; - else if (isVisualBlockMode()) - m_rangemode = RangeBlockMode; - // FIXME: Consolidate. - if (isVisualMode()) { - leaveVisualMode(); - m_replacement = input.text(); - finishMovement(); - } else { - Range range(position(), position() + count(), RangeCharMode); - m_replacement = input.text(); - Transformation tr = &FakeVimHandler::Private::replaceTransform; - transformText(range, tr); - m_subsubmode = NoSubSubMode; - m_submode = NoSubMode; - setDotCommand("%1r" + input.text(), count()); - finishMovement(); - } } else if (m_subsubmode == MarkSubSubMode) { setMark(input.asChar().unicode(), m_tc.position()); m_subsubmode = NoSubSubMode; @@ -1701,6 +1676,28 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) m_register = input.asChar().unicode(); m_submode = NoSubMode; m_rangemode = RangeLineMode; + } else if (m_submode == ReplaceSubMode) { + if (isVisualMode()) { + if (isVisualLineMode()) + m_rangemode = RangeLineMode; + else if (isVisualBlockMode()) + m_rangemode = RangeBlockMode; + else + m_rangemode = RangeCharMode; + leaveVisualMode(); + Range range = currentRange(); + Transformation tr = &FakeVimHandler::Private::replaceTransform; + transformText(range, tr, input.asChar()); + setPosition(range.beginPos); + } else if (count() <= rightDist()) { + setAnchor(); + moveRight(count()); + replaceText(currentRange(), QString(count(), input.asChar())); + moveLeft(); + setDotCommand("%1r" + input.text(), count()); + } + m_submode = NoSubMode; + finishMovement(); } else if (m_submode == ChangeSubMode && input.is('c')) { // tested moveToStartOfLine(); setAnchor(); @@ -2250,8 +2247,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) setDotCommand("%1p", count()); finishMovement(); } else if (input.is('r')) { - m_submode = TransformSubMode; - m_subsubmode = ReplaceSubSubMode; + m_submode = ReplaceSubMode; } else if (!isVisualMode() && input.is('R')) { setUndoPosition(position()); breakEditBlock(); @@ -3983,6 +3979,8 @@ void FakeVimHandler::Private::transformText(const Range &range, QTextCursor tc = m_tc; switch (range.rangemode) { case RangeCharMode: { + // This can span multiple lines. + beginEditBlock(); tc.setPosition(range.beginPos, MoveAnchor); tc.setPosition(range.endPos, KeepAnchor); TransformationData td(tc.selectedText(), extra); @@ -3990,10 +3988,12 @@ void FakeVimHandler::Private::transformText(const Range &range, tc.removeSelectedText(); fixMarks(range.beginPos, td.to.size() - td.from.size()); tc.insertText(td.to); + endEditBlock(); return; } case RangeLineMode: case RangeLineModeExclusive: { + beginEditBlock(range.beginPos); tc.setPosition(range.beginPos, MoveAnchor); tc.movePosition(StartOfLine, MoveAnchor); tc.setPosition(range.endPos, KeepAnchor); @@ -4020,6 +4020,7 @@ void FakeVimHandler::Private::transformText(const Range &range, tc.removeSelectedText(); fixMarks(range.beginPos, td.to.size() - td.from.size()); tc.insertText(td.to); + endEditBlock(); return; } case RangeBlockAndTailMode: @@ -4107,13 +4108,7 @@ void FakeVimHandler::Private::replaceText(const Range &range, const QString &str void FakeVimHandler::Private::replaceTransform(TransformationData *td) { - for (int i = td->from.size(); --i >= 0; ) { - QChar c = td->from.at(i); - if (c.unicode() == '\n' || c.unicode() == '\0') - td->to += QLatin1Char('\n'); - else - td->to += td->extraData.toString(); - } + td->to = QString(td->from.size(), td->extraData.toChar()); } void FakeVimHandler::Private::pasteText(bool afterCursor)