diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 5b6dd910513d6f7a71eb2af430ec07de4fed755f..057cf211bc71b84a7d46aa0c3f7898bf1355d70d 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -205,7 +205,8 @@ private: { return m_tc.atBlockEnd() && m_tc.block().length() > 1; } int lastPositionInDocument() const; - int positionForLine(int line) const; // 1 based line, 0 based pos + int firstPositionInLine(int line) const; // 1 based line, 0 based pos + int lastPositionInLine(int line) const; // 1 based line, 0 based pos int lineForPosition(int pos) const; // 1 based line, 0 based pos // all zero-based counting @@ -242,8 +243,6 @@ private: void moveLeft(int n = 1) { m_tc.movePosition(Left, MoveAnchor, n); } void setAnchor() { m_anchor = m_tc.position(); } - QString selectedText() const; - void handleFfTt(int key); // helper function for handleCommand. return 1 based line index. @@ -307,6 +306,8 @@ public: void recordEndGroup(); int anchor() const { return m_anchor; } int position() const { return m_tc.position(); } + QString selectedText() const; + void undo(); void redo(); @@ -442,6 +443,21 @@ void FakeVimHandler::Private::setupWidget() } m_wasReadOnly = EDITOR(isReadOnly()); //EDITOR(setReadOnly(true)); + + QTextCursor tc = EDITOR(textCursor()); + if (tc.hasSelection()) { + int pos = tc.position(); + int anc = tc.anchor(); + m_marks['<'] = anc; + m_marks['>'] = pos; + m_anchor = anc; + m_visualMode = VisualCharMode; + tc.clearSelection(); + EDITOR(setTextCursor(tc)); + m_tc = tc; // needed in updateSelection + updateSelection(); + } + showBlackMessage("vi emulation mode."); updateMiniBuffer(); } @@ -452,6 +468,23 @@ void FakeVimHandler::Private::restoreWidget() //updateMiniBuffer(); EDITOR(removeEventFilter(q)); EDITOR(setReadOnly(m_wasReadOnly)); + + if (m_visualMode == VisualLineMode) { + m_tc = EDITOR(textCursor()); + int beginLine = lineForPosition(m_marks['<']); + int endLine = lineForPosition(m_marks['>']); + m_tc.setPosition(firstPositionInLine(beginLine), MoveAnchor); + m_tc.setPosition(lastPositionInLine(endLine), KeepAnchor); + EDITOR(setTextCursor(m_tc)); + } else if (m_visualMode == VisualCharMode) { + m_tc = EDITOR(textCursor()); + m_tc.setPosition(m_marks['<'], MoveAnchor); + m_tc.setPosition(m_marks['>'], KeepAnchor); + EDITOR(setTextCursor(m_tc)); + } + + m_visualMode = NoVisualMode; + updateSelection(); } bool FakeVimHandler::Private::handleKey(int key, int unmodified, const QString &text) @@ -696,21 +729,21 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, //qDebug() << "Z_MODE " << cursorLineInDocument() << linesOnScreen(); if (key == Key_Return || key == 't') { // cursor line to top of window if (!m_mvcount.isEmpty()) - m_tc.setPosition(positionForLine(count())); + m_tc.setPosition(firstPositionInLine(count())); scrollToLineInDocument(cursorLineInDocument()); if (key == Key_Return) moveToFirstNonBlankOnLine(); finishMovement(); } else if (key == '.' || key == 'z') { // cursor line to center of window if (!m_mvcount.isEmpty()) - m_tc.setPosition(positionForLine(count())); + m_tc.setPosition(firstPositionInLine(count())); scrollToLineInDocument(cursorLineInDocument() - linesOnScreen() / 2); if (key == '.') moveToFirstNonBlankOnLine(); finishMovement(); } else if (key == '-' || key == 'b') { // cursor line to bottom of window if (!m_mvcount.isEmpty()) - m_tc.setPosition(positionForLine(count())); + m_tc.setPosition(firstPositionInLine(count())); scrollToLineInDocument(cursorLineInDocument() - linesOnScreen() - 1); if (key == '-') moveToFirstNonBlankOnLine(); @@ -921,7 +954,7 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified, m_gflag = true; } else if (key == 'G') { int n = m_mvcount.isEmpty() ? linesInDocument() : count(); - m_tc.setPosition(positionForLine(n), KeepAnchor); + m_tc.setPosition(firstPositionInLine(n), KeepAnchor); if (m_config[ConfigStartOfLine] == ConfigOn) moveToFirstNonBlankOnLine(); finishMovement(); @@ -1413,12 +1446,12 @@ int FakeVimHandler::Private::readLineCode(QString &cmd) void FakeVimHandler::Private::selectRange(int beginLine, int endLine) { - m_anchor = positionForLine(beginLine); + m_anchor = firstPositionInLine(beginLine); if (endLine == linesInDocument()) { - m_tc.setPosition(positionForLine(endLine), MoveAnchor); + m_tc.setPosition(firstPositionInLine(endLine), MoveAnchor); m_tc.movePosition(EndOfLine, MoveAnchor); } else { - m_tc.setPosition(positionForLine(endLine + 1), MoveAnchor); + m_tc.setPosition(firstPositionInLine(endLine + 1), MoveAnchor); } } @@ -1450,7 +1483,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0) static QRegExp reHistory("^his(tory)?( (.*))?$"); if (cmd.isEmpty()) { - m_tc.setPosition(positionForLine(beginLine)); + m_tc.setPosition(firstPositionInLine(beginLine)); showBlackMessage(QString()); } else if (cmd == "q!" || cmd == "q") { // :q quit(); @@ -1471,7 +1504,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0) beginLine = 0; if (endLine == -1) endLine = linesInDocument(); - qDebug() << "LINES: " << beginLine << endLine; + //qDebug() << "LINES: " << beginLine << endLine; bool forced = cmd.startsWith("w!"); QString fileName = reWrite.cap(2); if (fileName.isEmpty()) @@ -1541,7 +1574,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0) recordEndGroup(); leaveVisualMode(); - m_tc.setPosition(positionForLine(beginLine)); + m_tc.setPosition(firstPositionInLine(beginLine)); EditOperation op; // FIXME: broken for "upward selection" op.position = m_tc.position(); @@ -1906,11 +1939,17 @@ QString FakeVimHandler::Private::selectedText() const return tc.selection().toPlainText(); } -int FakeVimHandler::Private::positionForLine(int line) const +int FakeVimHandler::Private::firstPositionInLine(int line) const { return m_tc.block().document()->findBlockByNumber(line - 1).position(); } +int FakeVimHandler::Private::lastPositionInLine(int line) const +{ + QTextBlock block = m_tc.block().document()->findBlockByNumber(line - 1); + return block.position() + block.length() - 1; +} + int FakeVimHandler::Private::lineForPosition(int pos) const { QTextCursor tc = m_tc;