diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index ec3f12cd6cc..cb7c685a263 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -865,7 +865,7 @@ public: QString lineContents(int line) const; // 1 based line void setLineContents(int line, const QString &contents); // 1 based line int blockBoundary(const QString &left, const QString &right, - bool end) const; // end or start position of current code block + bool end, int count) const; // end or start position of current code block int linesOnScreen() const; int columnsOnScreen() const; @@ -4911,32 +4911,34 @@ void FakeVimHandler::Private::setLineContents(int line, const QString &contents) } int FakeVimHandler::Private::blockBoundary(const QString &left, - const QString &right, bool closing) const + const QString &right, bool closing, int count) const { const QString &begin = closing ? left : right; const QString &end = closing ? right : left; - // match even if cursor is already on opening/closing string - // - on opening string: + // shift cursor if it is already on opening/closing string QTextCursor tc1 = cursor(); int pos = tc1.position(); + int max = document()->characterCount(); int sz = left.size(); - tc1.setPosition(qMax(pos - sz + 1, 0)); - tc1 = document()->find(left, tc1); - if (!tc1.isNull() && (tc1.position() - pos) <= sz) { - if (!closing) - return tc1.position() - sz; + int from = qMax(pos - sz + 1, 0); + int to = qMin(pos + sz, max); + tc1.setPosition(from); + tc1.setPosition(to, KeepAnchor); + int i = tc1.selectedText().indexOf(left); + if (i != -1) { + // - on opening string: + tc1.setPosition(from + i + sz); } else { - // - on closing string: - tc1 = cursor(); sz = right.size(); - tc1.setPosition(qMax(pos - sz + 1, 0)); - tc1 = document()->find(right, tc1); - if (!tc1.isNull() && (tc1.position() - pos) <= sz) { - if (closing) - return tc1.position() - sz; - else - tc1.setPosition(tc1.position() - sz); + from = qMax(pos - sz + 1, 0); + to = qMin(pos + sz, max); + tc1.setPosition(from); + tc1.setPosition(to, KeepAnchor); + i = tc1.selectedText().indexOf(right); + if (i != -1) { + // - on closing string: + tc1.setPosition(from + i); } else { tc1 = cursor(); } @@ -4945,11 +4947,13 @@ int FakeVimHandler::Private::blockBoundary(const QString &left, QTextCursor tc2 = tc1; QTextDocument::FindFlags flags(closing ? 0 : QTextDocument::FindBackward); int level = 0; + int counter = 0; while (true) { tc2 = document()->find(end, tc2, flags); if (tc2.isNull()) return -1; - tc1 = document()->find(begin, tc1, flags); + if (!tc1.isNull()) + tc1 = document()->find(begin, tc1, flags); while (!tc1.isNull() && (closing ? (tc1 < tc2) : (tc2 < tc1))) { ++level; @@ -4966,7 +4970,9 @@ int FakeVimHandler::Private::blockBoundary(const QString &left, if (level == 0 && (tc1.isNull() || (closing ? (tc2 < tc1) : (tc1 < tc2)))) { - break; + ++counter; + if (counter >= count) + break; } } @@ -5245,19 +5251,17 @@ void FakeVimHandler::Private::selectBlockTextObject(bool inner, QString sleft = QString(QLatin1Char(left)); QString sright = QString(QLatin1Char(right)); - int p1 = blockBoundary(sleft, sright, false); + int p1 = blockBoundary(sleft, sright, false, count()); if (p1 == -1) return; - int p2 = blockBoundary(sleft, sright, true); + int p2 = blockBoundary(sleft, sright, true, count()); if (p2 == -1) return; if (inner) { p1 += sleft.size(); --p2; - if (document()->characterAt(p1) == ParagraphSeparator) - ++p1; } else { p2 -= sright.size() - 1; }