diff --git a/src/plugins/fakevim/handler.cpp b/src/plugins/fakevim/handler.cpp index 16550f5ef5889132516db1c814bf2b8ae15f53b6..1e8931cb83ab5d41760c949148137fc1813c422e 100644 --- a/src/plugins/fakevim/handler.cpp +++ b/src/plugins/fakevim/handler.cpp @@ -46,6 +46,7 @@ #include <QtGui/QScrollBar> #include <QtGui/QTextBlock> #include <QtGui/QTextCursor> +#include <QtGui/QTextDocumentFragment> #include <QtGui/QTextEdit> @@ -131,6 +132,7 @@ public: bool atEol() const { return m_tc.atBlockEnd() && m_tc.block().length()>1; } int lastPositionInDocument() const; + int positionForLine(int line) const; // 1 based // all zero-based counting int cursorLineOnScreen() const; @@ -149,6 +151,7 @@ public: // helper function for handleCommand. return 1 based line index. int readLineCode(QString &cmd); + QTextCursor selectRange(int beginLine, int endLine); FakeVimHandler *q; Mode m_mode; @@ -360,7 +363,7 @@ void FakeVimHandler::Private::handleCommandMode(int key, const QString &text) } else if (m_subsubmode == BackTickSubSubMode || m_subsubmode == TickSubSubMode) { if (m_marks.contains(key)) { - m_tc.setPosition(m_marks[key]); + m_tc.setPosition(m_marks[key], MoveAnchor); if (m_subsubmode == TickSubSubMode) moveToFirstNonBlankOnLine(); finishMovement(); @@ -453,7 +456,7 @@ void FakeVimHandler::Private::handleCommandMode(int key, const QString &text) m_gflag = true; } else if (key == 'G') { int n = m_mvcount.isEmpty() ? linesInDocument() : count(); - m_tc.setPosition(m_tc.document()->findBlockByNumber(n - 1).position()); + m_tc.setPosition(positionForLine(n), MoveAnchor); if (m_config.contains(ConfigStartOfLine)) moveToFirstNonBlankOnLine(); finishMovement(); @@ -754,6 +757,14 @@ int FakeVimHandler::Private::readLineCode(QString &cmd) return -1; } +QTextCursor FakeVimHandler::Private::selectRange(int beginLine, int endLine) +{ + QTextCursor tc = m_tc; + tc.setPosition(positionForLine(beginLine), MoveAnchor); + tc.setPosition(positionForLine(endLine + 1), KeepAnchor); + return tc; +} + void FakeVimHandler::Private::handleCommand(const QString &cmd0) { QString cmd = cmd0; @@ -777,15 +788,29 @@ void FakeVimHandler::Private::handleCommand(const QString &cmd0) //qDebug() << "RANGE: " << beginLine << endLine << cmd << cmd0; static QRegExp reWrite("^w!?( (.*))?$"); + static QRegExp reDelete("^d( (.*))?$"); if (cmd.isEmpty()) { - m_tc.setPosition(m_tc.block().document() - ->findBlockByNumber(beginLine - 1).position()); + m_tc.setPosition(positionForLine(beginLine)); showMessage(QString()); - } else if (cmd == "q!" || cmd == "q") { + } else if (cmd == "q!" || cmd == "q") { // :q q->quitRequested(THE_EDITOR); showMessage(QString()); - } else if (reWrite.indexIn(cmd) != -1) { + } else if (reDelete.indexIn(cmd) != -1) { // :d + if (beginLine == -1) + beginLine = cursorLineInDocument(); + if (endLine == -1) + endLine = cursorLineInDocument(); + QTextCursor tc = selectRange(beginLine, endLine); + QString reg = reDelete.cap(2); + if (!reg.isEmpty()) + m_registers[reg.at(0).unicode()] = tc.selection().toPlainText(); + tc.removeSelectedText(); + } else if (reWrite.indexIn(cmd) != -1) { // :w + if (beginLine == -1) + beginLine = 0; + if (endLine == -1) + endLine = linesInDocument(); bool forced = cmd.startsWith("w!"); QString fileName = reWrite.cap(2); if (fileName.isEmpty()) @@ -796,8 +821,10 @@ void FakeVimHandler::Private::handleCommand(const QString &cmd0) showMessage("E13: File exists (add ! to override)"); } else { file.open(QIODevice::ReadWrite); + QTextCursor tc = selectRange(beginLine, endLine); + QString text = tc.selection().toPlainText(); QTextStream ts(&file); - ts << EDITOR(toPlainText()); + ts << text; file.close(); file.open(QIODevice::ReadWrite); QByteArray ba = file.readAll(); @@ -1010,6 +1037,11 @@ QString FakeVimHandler::Private::lastSearchString() const return m_searchHistory.empty() ? QString() : m_searchHistory.back(); } +int FakeVimHandler::Private::positionForLine(int line) const +{ + return m_tc.block().document()->findBlockByNumber(line - 1).position(); +} + /////////////////////////////////////////////////////////////////////// // // FakeVimHandler