diff --git a/src/plugins/fakevim/handler.cpp b/src/plugins/fakevim/handler.cpp index 0fe177cbc0dc8a3819581007dc6bd5dbbd5ea666..6c4ff474a608d7a6337a04938dbcb58b4de4c72f 100644 --- a/src/plugins/fakevim/handler.cpp +++ b/src/plugins/fakevim/handler.cpp @@ -120,7 +120,9 @@ public: void scrollToLineInDocument(int line); void moveToFirstNonBlankOnLine(); - void moveWord(int repeat, bool simple); + void moveToNextWord(int repeat, bool simple); + void moveToWordBegin(int repeat, bool simple); + void moveToWordEnd(int repeat, bool simple); FakeVimHandler *q; Mode m_mode; @@ -301,6 +303,12 @@ void FakeVimHandler::Private::handleCommandMode(int key, const QString &text) } else if (key == 'A') { m_tc.movePosition(EndOfLine, MoveAnchor); m_mode = InsertMode; + } else if (key == 'b') { + moveToWordBegin(count(), false); + finishMovement(); + } else if (key == 'B') { + moveToWordBegin(count(), true); + finishMovement(); } else if (key == 'c') { m_submode = ChangeSubMode; } else if (key == 'C') { @@ -315,6 +323,12 @@ void FakeVimHandler::Private::handleCommandMode(int key, const QString &text) m_submode = DeleteSubMode; m_tc.movePosition(EndOfLine, KeepAnchor); finishMovement(); + } else if (key == 'e') { + moveToWordEnd(count(), false); + finishMovement(); + } else if (key == 'E') { + moveToWordEnd(count(), true); + finishMovement(); } else if (key == 'h' || key == Key_Left) { int n = qMin(count(), leftDist()); if (m_fakeEnd && m_tc.block().length() > 1) @@ -370,10 +384,10 @@ void FakeVimHandler::Private::handleCommandMode(int key, const QString &text) } else if (key == 'u') { m_editor->undo(); } else if (key == 'w') { - moveWord(count(), false); + moveToNextWord(count(), false); finishMovement(); } else if (key == 'W') { - moveWord(count(), true); + moveToNextWord(count(), true); finishMovement(); } else if (key == 'x') { // = "dl" if (atEol()) @@ -528,7 +542,43 @@ static int charClass(QChar c, bool simple) return c.isSpace() ? 0 : 1; } -void FakeVimHandler::Private::moveWord(int repeat, bool simple) +void FakeVimHandler::Private::moveToWordBegin(int repeat, bool simple) +{ + QTextDocument *doc = m_tc.document(); + int n = lastPositionInDocument() - 1; + int lastClass = 0; + while (m_tc.position() < n) { + QChar c = doc->characterAt(m_tc.position()); + int thisClass = charClass(c, simple); + if (thisClass != lastClass && thisClass != 0) + --repeat; + if (repeat == -1) + return; + lastClass = thisClass; + m_tc.movePosition(Right, KeepAnchor, 1); + } +} + +void FakeVimHandler::Private::moveToWordEnd(int repeat, bool simple) +{ + QTextDocument *doc = m_tc.document(); + int n = lastPositionInDocument() - 1; + int lastClass = 0; + while (m_tc.position() < n) { + QChar c = doc->characterAt(m_tc.position()); + int thisClass = charClass(c, simple); + if (thisClass != lastClass && lastClass != 0) + --repeat; + if (repeat == -1) { + m_tc.movePosition(Left, KeepAnchor, 1); + return; + } + lastClass = thisClass; + m_tc.movePosition(Right, KeepAnchor, 1); + } +} + +void FakeVimHandler::Private::moveToNextWord(int repeat, bool simple) { // FIXME: 'w' should stop on empty lines, too QTextDocument *doc = m_tc.document();