diff --git a/src/plugins/fakevim/fakevim_test.cpp b/src/plugins/fakevim/fakevim_test.cpp index 271f24a21a810068e638410e3417da2f6f666d21..2e3125e94826498a67d45e035d859255d101cb4d 100644 --- a/src/plugins/fakevim/fakevim_test.cpp +++ b/src/plugins/fakevim/fakevim_test.cpp @@ -2514,6 +2514,21 @@ void FakeVimPlugin::test_map() KEYS("f<space>", "abc" N "x " X " z" N "def"); KEYS("t<space>", "abc" N "x " X " z" N "def"); data.doCommand("unmap <SPACE>"); + + // operator-pending mappings + data.setText("abc def" N "ghi jkl"); + data.doCommand("omap <SPACE> aw"); + KEYS("c<space>X<esc>", X "Xdef" N "ghi jkl"); + data.doCommand("onoremap <SPACE> iwX"); + KEYS("c<space>Y<esc>", "X" X "Y" N "ghi jkl"); + data.doCommand("ono <SPACE> l"); + KEYS("d<space>", X "X" N "ghi jkl"); + data.doCommand("unmap <SPACE>"); + + data.setText("abc def" N "ghi jkl"); + data.doCommand("onoremap iwwX 3iwX Y"); + KEYS("ciwwX Z<esc>", "X Y " X "Z" N "ghi jkl"); + data.doCommand("unmap <SPACE>X"); } void FakeVimPlugin::test_vim_command_cc() diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index c13ea02e930044279fb454f1f7047df097c41ab1..4e9c2d05d1aaafe568eb232695138aad3b09c8c8 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -1522,7 +1522,6 @@ public: bool handleCommandSubSubMode(const Input &); void fixSelection(); // Fix selection according to current range, move and command modes. void finishMovement(const QString &dotCommandMovement = QString()); - void finishMovement(const QString &dotCommandMovement, int count); void resetCommandMode(); void clearCommandMode(); QTextCursor search(const SearchData &sd, int startPos, int count, bool showMessages); @@ -1716,6 +1715,18 @@ public: Q_SLOT void onUndoCommandAdded(); bool isInsertMode() const { return g.mode == InsertMode || g.mode == ReplaceMode; } + // Waiting for movement operator. + bool isOperatorPending() const { + return g.submode == ChangeSubMode + || g.submode == DeleteSubMode + || g.submode == FilterSubMode + || g.submode == IndentSubMode + || g.submode == ShiftLeftSubMode + || g.submode == ShiftRightSubMode + || g.submode == InvertCaseSubMode + || g.submode == DownCaseSubMode + || g.submode == UpCaseSubMode + || g.submode == YankSubMode; } bool isVisualMode() const { return g.visualMode != NoVisualMode; } bool isNoVisualMode() const { return g.visualMode == NoVisualMode; } @@ -3004,11 +3015,6 @@ void FakeVimHandler::Private::fixSelection() } } -void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement, int count) -{ - finishMovement(dotCommandMovement.arg(count)); -} - void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) { //dump("FINISH MOVEMENT"); @@ -3755,6 +3761,9 @@ EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) handled = handleChangeCaseSubMode(input); } + if (!handled && isOperatorPending()) + handled = handleMovement(input); + // Clear state and display incomplete command if necessary. if (handled) { bool noMode = @@ -4253,8 +4262,6 @@ bool FakeVimHandler::Private::handleChangeDeleteSubModes(const Input &input) finishMovement(); g.submode = NoSubMode; handled = true; - } else { - handled = handleMovement(input); } return handled; @@ -4305,9 +4312,9 @@ bool FakeVimHandler::Private::handleReplaceSubMode(const Input &input) return handled; } -bool FakeVimHandler::Private::handleFilterSubMode(const Input &input) +bool FakeVimHandler::Private::handleFilterSubMode(const Input &) { - return handleMovement(input); + return false; } bool FakeVimHandler::Private::handleRegisterSubMode(const Input &input) @@ -4338,8 +4345,6 @@ bool FakeVimHandler::Private::handleShiftSubMode(const Input &input) finishMovement(); handled = true; g.submode = NoSubMode; - } else { - handled = handleMovement(input); } return handled; } @@ -4361,8 +4366,6 @@ bool FakeVimHandler::Private::handleChangeCaseSubMode(const Input &input) finishMovement(QString::fromLatin1("%1%2").arg(count()).arg(input.raw())); handled = true; g.submode = NoSubMode; - } else { - handled = handleMovement(input); } return handled; } @@ -4388,8 +4391,6 @@ bool FakeVimHandler::Private::handleYankSubMode(const Input &input) yankText(range, m_register); g.submode = NoSubMode; handled = true; - } else { - handled = handleMovement(input); } return handled; } @@ -5189,6 +5190,7 @@ bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map if (cmd == "vm" || cmd == "vmap") { modes = "v"; type = Map; } else if (cmd == "xm" || cmd == "xmap") { modes = "x"; type = Map; } else if (cmd == "smap") { modes = "s"; type = Map; } else + if (cmd == "omap") { modes = "o"; type = Map; } else if (cmd == "map!") { modes = "ic"; type = Map; } else if (cmd == "im" || cmd == "imap") { modes = "i"; type = Map; } else if (cmd == "lm" || cmd == "lmap") { modes = "l"; type = Map; } else @@ -7271,14 +7273,16 @@ void FakeVimHandler::Private::onUndoCommandAdded() char FakeVimHandler::Private::currentModeCode() const { - if (g.submode != NoSubMode) - return ' '; - else if (g.mode == ExMode) + if (g.mode == ExMode) return 'c'; else if (isVisualMode()) return 'v'; + else if (isOperatorPending()) + return 'o'; else if (g.mode == CommandMode) return 'n'; + else if (g.submode != NoSubMode) + return ' '; else return 'i'; }