diff options
Diffstat (limited to 'src/plugins/fakevim/fakevimhandler.cpp')
-rw-r--r-- | src/plugins/fakevim/fakevimhandler.cpp | 157 |
1 files changed, 89 insertions, 68 deletions
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 601377ed69..66ebe44a46 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -63,7 +63,7 @@ #include <QObject> #include <QPointer> #include <QProcess> -#include <QRegExp> +#include <QRegularExpression> #include <QTextStream> #include <QTimer> #include <QStack> @@ -387,9 +387,9 @@ static bool eatString(const QString &prefix, QString *str) return true; } -static QRegExp vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool smartCaseOption) +static QRegularExpression vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool smartCaseOption) { - /* Transformations (Vim regexp -> QRegExp): + /* Transformations (Vim regexp -> QRegularExpression): * \a -> [A-Za-z] * \A -> [^A-Za-z] * \h -> [A-Za-z_] @@ -420,7 +420,7 @@ static QRegExp vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool */ // FIXME: Option smartcase should be used only if search was typed by user. bool ignorecase = ignoreCaseOption - && !(smartCaseOption && needle.contains(QRegExp("[A-Z]"))); + && !(smartCaseOption && needle.contains(QRegularExpression("[A-Z]"))); QString pattern; pattern.reserve(2 * needle.size()); @@ -530,7 +530,7 @@ static QRegExp vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool else if (brace) pattern.append('['); - return QRegExp(pattern); + return QRegularExpression(pattern); } static bool afterEndOfLine(const QTextDocument *doc, int position) @@ -539,7 +539,7 @@ static bool afterEndOfLine(const QTextDocument *doc, int position) && doc->findBlock(position).length() > 1; } -static void searchForward(QTextCursor *tc, QRegExp &needleExp, int *repeat) +static void searchForward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat) { const QTextDocument *doc = tc->document(); const int startPos = tc->position(); @@ -577,16 +577,18 @@ static void searchForward(QTextCursor *tc, QRegExp &needleExp, int *repeat) tc->movePosition(Left); } -static void searchBackward(QTextCursor *tc, QRegExp &needleExp, int *repeat) +static void searchBackward(QTextCursor *tc, const QRegularExpression &needleExp, int *repeat) { // Search from beginning of line so that matched text is the same. QTextBlock block = tc->block(); QString line = block.text(); - int i = line.indexOf(needleExp, 0); + QRegularExpressionMatch match; + int i = line.indexOf(needleExp, 0, &match); while (i != -1 && i < tc->positionInBlock()) { --*repeat; - i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength())); + const int offset = i + qMax(1, match.capturedLength()); + i = line.indexOf(needleExp, offset, &match); if (i == line.size()) i = -1; } @@ -599,10 +601,11 @@ static void searchBackward(QTextCursor *tc, QRegExp &needleExp, int *repeat) if (!block.isValid()) break; line = block.text(); - i = line.indexOf(needleExp, 0); + i = line.indexOf(needleExp, 0, &match); while (i != -1) { --*repeat; - i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength())); + const int offset = i + qMax(1, match.capturedLength()); + i = line.indexOf(needleExp, offset, &match); if (i == line.size()) i = -1; } @@ -613,19 +616,20 @@ static void searchBackward(QTextCursor *tc, QRegExp &needleExp, int *repeat) return; } - i = line.indexOf(needleExp, 0); + i = line.indexOf(needleExp, 0, &match); while (*repeat < 0) { - i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength())); + const int offset = i + qMax(1, match.capturedLength()); + i = line.indexOf(needleExp, offset, &match); ++*repeat; } tc->setPosition(block.position() + i); - tc->setPosition(tc->position() + needleExp.matchedLength(), KeepAnchor); + tc->setPosition(tc->position() + match.capturedLength(), KeepAnchor); } // Commands [[, [] static void bracketSearchBackward(QTextCursor *tc, const QString &needleExp, int repeat) { - QRegExp re(needleExp); + const QRegularExpression re(needleExp); QTextCursor tc2 = *tc; tc2.setPosition(tc2.position() - 1); searchBackward(&tc2, re, &repeat); @@ -638,7 +642,7 @@ static void bracketSearchBackward(QTextCursor *tc, const QString &needleExp, int static void bracketSearchForward(QTextCursor *tc, const QString &needleExp, int repeat, bool searchWithCommand) { - QRegExp re(searchWithCommand ? QString("^\\}|^\\{") : needleExp); + QRegularExpression re(searchWithCommand ? QString("^\\}|^\\{") : needleExp); QTextCursor tc2 = *tc; tc2.setPosition(tc2.position() + 1); searchForward(&tc2, re, &repeat); @@ -668,17 +672,21 @@ static char backslashed(char t) return t; } -static bool substituteText(QString *text, QRegExp &pattern, const QString &replacement, - bool global) +static bool substituteText(QString *text, + const QRegularExpression &pattern, + const QString &replacement, + bool global) { bool substituted = false; int pos = 0; int right = -1; while (true) { - pos = pattern.indexIn(*text, pos, QRegExp::CaretAtZero); - if (pos == -1) + const QRegularExpressionMatch match = pattern.match(*text, pos); + if (!match.hasMatch()) break; + pos = match.capturedStart(); + // ensure that substitution is advancing towards end of line if (right == text->size() - pos) { ++pos; @@ -690,7 +698,7 @@ static bool substituteText(QString *text, QRegExp &pattern, const QString &repla right = text->size() - pos; substituted = true; - QString matched = text->mid(pos, pattern.cap(0).size()); + QString matched = text->mid(pos, match.captured(0).size()); QString repl; bool escape = false; // insert captured texts @@ -699,8 +707,8 @@ static bool substituteText(QString *text, QRegExp &pattern, const QString &repla if (escape) { escape = false; if (c.isDigit()) { - if (c.digitValue() <= pattern.captureCount()) - repl += pattern.cap(c.digitValue()); + if (c.digitValue() <= match.lastCapturedIndex()) + repl += match.captured(c.digitValue()); } else { repl += backslashed(c.unicode()); } @@ -708,7 +716,7 @@ static bool substituteText(QString *text, QRegExp &pattern, const QString &repla if (c == '\\') escape = true; else if (c == '&') - repl += pattern.cap(0); + repl += match.captured(0); else repl += c; } @@ -893,6 +901,11 @@ static bool isOnlyControlModifier(const Qt::KeyboardModifiers &mods) return (mods ^ ControlModifier) == Qt::NoModifier; } +static bool hasControlModifier(const Qt::KeyboardModifiers &mods) +{ + return mods.testFlag(ControlModifier); +} + Range::Range(int b, int e, RangeMode m) : beginPos(qMin(b, e)), endPos(qMax(b, e)), rangemode(m) @@ -1065,7 +1078,7 @@ public: bool is(int c) const { - return m_xkey == c && !isControl(); + return m_xkey == c && !hasControlModifier(m_modifiers); } bool isControl() const @@ -1346,7 +1359,7 @@ class History public: History() : m_items(QString()) {} void append(const QString &item); - const QString &move(const QStringRef &prefix, int skip); + const QString &move(QStringView prefix, int skip); const QString ¤t() const { return m_items[m_index]; } const QStringList &items() const { return m_items; } void restart() { m_index = m_items.size() - 1; } @@ -1367,7 +1380,7 @@ void History::append(const QString &item) restart(); } -const QString &History::move(const QStringRef &prefix, int skip) +const QString &History::move(QStringView prefix, int skip) { if (!current().startsWith(prefix)) restart(); @@ -1397,7 +1410,7 @@ public: m_buffer = s; m_pos = m_userPos = pos; m_anchor = anchor >= 0 ? anchor : pos; } - QStringRef userContents() const { return m_buffer.leftRef(m_userPos); } + QStringView userContents() const { return QStringView{m_buffer}.left(m_userPos); } const QChar &prompt() const { return m_prompt; } const QString &contents() const { return m_buffer; } bool isEmpty() const { return m_buffer.isEmpty(); } @@ -1418,8 +1431,9 @@ public: void moveEnd() { m_userPos = m_pos = m_buffer.size(); } void setHistoryAutoSave(bool autoSave) { m_historyAutoSave = autoSave; } - void historyDown() { setContents(m_history.move(userContents(), 1)); } - void historyUp() { setContents(m_history.move(userContents(), -1)); } + bool userContentsValid() const { return m_userPos >= 0 && m_userPos <= m_buffer.size(); } + void historyDown() { if (userContentsValid()) setContents(m_history.move(userContents(), 1)); } + void historyUp() { if (userContentsValid()) setContents(m_history.move(userContents(), -1)); } const QStringList &historyItems() const { return m_history.items(); } void historyPush(const QString &item = QString()) { @@ -1590,7 +1604,7 @@ public: bool walk(const Inputs &inputs) { - foreach (const Input &input, inputs) { + for (const Input &input : inputs) { if (!walk(input)) return false; } @@ -1628,7 +1642,7 @@ public: void setInputs(const Inputs &key, const Inputs &inputs, bool unique = false) { ModeMapping *current = &(*m_parent)[m_mode]; - foreach (const Input &input, key) + for (const Input &input : key) current = &(*current)[input]; if (!unique || current->value().isEmpty()) current->setValue(inputs); @@ -2626,7 +2640,7 @@ void FakeVimHandler::Private::commitInsertState() lastInsertion.prepend(QString("<DELETE>").repeated(insertState.deletes)); // Remove indentation. - lastInsertion.replace(QRegExp("(^|\n)[\\t ]+"), "\\1"); + lastInsertion.replace(QRegularExpression("(^|\n)[\\t ]+"), "\\1"); } void FakeVimHandler::Private::invalidateInsertState() @@ -2850,7 +2864,7 @@ void FakeVimHandler::Private::prependMapping(const Inputs &inputs) // FIXME: Implement Vim option maxmapdepth (default value is 1000). if (g.mapDepth >= 1000) { const int i = qMax(0, g.pendingInput.lastIndexOf(Input())); - QList<Input> inputs = g.pendingInput.mid(i); + const QList<Input> inputs = g.pendingInput.mid(i); clearPendingInput(); g.pendingInput.append(inputs); showMessage(MessageError, Tr::tr("Recursive mapping")); @@ -3913,7 +3927,7 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) QString needle; QTextCursor tc = m_cursor; tc.select(QTextCursor::WordUnderCursor); - needle = QRegExp::escape(tc.selection().toPlainText()); + needle = QRegularExpression::escape(tc.selection().toPlainText()); if (!g.gflag) { needle.prepend("\\<"); needle.append("\\>"); @@ -4598,7 +4612,7 @@ bool FakeVimHandler::Private::handleReplaceSubMode(const Input &input) ++range.endPos; // Replace each character but preserve lines. transformText(range, [&c](const QString &text) { - return QString(text).replace(QRegExp("[^\\n]"), c); + return QString(text).replace(QRegularExpression("[^\\n]"), c); }); } else if (count() <= rightDist()) { pushUndoState(); @@ -5427,7 +5441,7 @@ bool FakeVimHandler::Private::parseExCommand(QString *line, ExCommand *cmd) cmd->cmd = line->mid(0, i).trimmed(); // command arguments starts with first non-letter character - cmd->args = cmd->cmd.section(QRegExp("(?=[^a-zA-Z])"), 1); + cmd->args = cmd->cmd.section(QRegularExpression("(?=[^a-zA-Z])"), 1); if (!cmd->args.isEmpty()) { cmd->cmd.chop(cmd->args.size()); cmd->args = cmd->args.trimmed(); @@ -5447,7 +5461,7 @@ bool FakeVimHandler::Private::parseExCommand(QString *line, ExCommand *cmd) bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd) { // remove leading colons and spaces - line->remove(QRegExp("^\\s*(:+\\s*)*")); + line->remove(QRegularExpression("^\\s*(:+\\s*)*")); // special case ':!...' (use invalid range) if (line->startsWith('!')) { @@ -5506,10 +5520,10 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) int count = 1; QString line = cmd.args; - const int countIndex = line.lastIndexOf(QRegExp("\\d+$")); - if (countIndex != -1) { - count = line.midRef(countIndex).toInt(); - line = line.mid(0, countIndex).trimmed(); + const QRegularExpressionMatch match = QRegularExpression("\\d+$").match(line); + if (match.hasMatch()) { + count = match.captured().toInt(); + line = line.left(match.capturedStart()).trimmed(); } if (cmd.cmd.isEmpty()) { @@ -5545,8 +5559,9 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) if (g.lastSubstituteFlags.contains('i')) needle.prepend("\\c"); - QRegExp pattern = vimPatternToQtPattern(needle, hasConfig(ConfigIgnoreCase), - hasConfig(ConfigSmartCase)); + const QRegularExpression pattern = vimPatternToQtPattern(needle, + hasConfig(ConfigIgnoreCase), + hasConfig(ConfigSmartCase)); QTextBlock lastBlock; QTextBlock firstBlock; @@ -5671,8 +5686,8 @@ bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map break; } - const QString lhs = args.section(QRegExp("\\s+"), 0, 0); - const QString rhs = args.section(QRegExp("\\s+"), 1); + const QString lhs = args.section(QRegularExpression("\\s+"), 0, 0); + const QString rhs = args.section(QRegularExpression("\\s+"), 1); if ((rhs.isNull() && type != Unmap) || (!rhs.isNull() && type == Unmap)) { // FIXME: Dump mappings here. //qDebug() << g.mappings; @@ -5735,7 +5750,7 @@ bool FakeVimHandler::Private::handleExRegisterCommand(const ExCommand &cmd) } QString info; info += "--- Registers ---\n"; - foreach (char reg, regs) { + for (char reg : qAsConst(regs)) { QString value = quoteUnprintable(registerContents(reg)); info += QString("\"%1 %2\n").arg(reg).arg(value); } @@ -5947,7 +5962,7 @@ bool FakeVimHandler::Private::handleExWriteCommand(const ExCommand &cmd) { // Note: The cmd.args.isEmpty() case is handled by handleExPluginCommand. // :w, :x, :wq, ... - //static QRegExp reWrite("^[wx]q?a?!?( (.*))?$"); + //static QRegularExpression reWrite("^[wx]q?a?!?( (.*))?$"); if (cmd.cmd != "w" && cmd.cmd != "x" && cmd.cmd != "wq") return false; @@ -6340,8 +6355,9 @@ void FakeVimHandler::Private::searchBalanced(bool forward, QChar needle, QChar o QTextCursor FakeVimHandler::Private::search(const SearchData &sd, int startPos, int count, bool showMessages) { - QRegExp needleExp = vimPatternToQtPattern(sd.needle, hasConfig(ConfigIgnoreCase), - hasConfig(ConfigSmartCase)); + const QRegularExpression needleExp = vimPatternToQtPattern(sd.needle, + hasConfig(ConfigIgnoreCase), + hasConfig(ConfigSmartCase)); if (!needleExp.isValid()) { if (showMessages) { QString error = needleExp.errorString(); @@ -6684,7 +6700,7 @@ void FakeVimHandler::Private::setupCharClass() m_charClass[i] = c.isSpace() ? 0 : 1; } const QString conf = config(ConfigIsKeyword).toString(); - foreach (const QString &part, conf.split(',')) { + for (const QString &part : conf.split(',')) { if (part.contains('-')) { const int from = someInt(part.section('-', 0, 0)); const int to = someInt(part.section('-', 1, 1)); @@ -7177,7 +7193,7 @@ void FakeVimHandler::Private::insertText(QTextCursor &tc, const QString &text) passEventToEditor(event, tc); } - foreach (QChar c, text) { + for (QChar c : text) { QKeyEvent event(QEvent::KeyPress, -1, Qt::NoModifier, QString(c)); passEventToEditor(event, tc); } @@ -7218,8 +7234,8 @@ void FakeVimHandler::Private::invertCase(const Range &range) [] (const QString &text) -> QString { QString result = text; for (int i = 0; i < result.length(); ++i) { - QCharRef c = result[i]; - c = c.isUpper() ? c.toLower() : c.toUpper(); + const QChar c = result[i]; + result[i] = c.isUpper() ? c.toLower() : c.toUpper(); } return result; }); @@ -8129,9 +8145,9 @@ void FakeVimHandler::Private::replay(const QString &command, int repeat) //qDebug() << "REPLAY: " << quoteUnprintable(command); clearCurrentMode(); - Inputs inputs(command); + const Inputs inputs(command); for (int i = 0; i < repeat; ++i) { - foreach (const Input &in, inputs) { + for (const Input &in : inputs) { if (handleDefaultKey(in) != EventHandled) return; } @@ -8389,17 +8405,22 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count) const int posMin = m_cursor.positionInBlock() + 1; // find first decimal, hexadecimal or octal number under or after cursor position - QRegExp re("(0[xX])(0*[0-9a-fA-F]+)|(0)(0*[0-7]+)(?=\\D|$)|(\\d+)"); - int pos = 0; - while ((pos = re.indexIn(lineText, pos)) != -1 && pos + re.matchedLength() < posMin) - ++pos; - if (pos == -1) - return false; - int len = re.matchedLength(); - QString prefix = re.cap(1) + re.cap(3); + QRegularExpression re("(0[xX])(0*[0-9a-fA-F]+)|(0)(0*[0-7]+)(?=\\D|$)|(\\d+)"); + QRegularExpressionMatch match; + QRegularExpressionMatchIterator it = re.globalMatch(lineText); + while (true) { + if (!it.hasNext()) + return false; + match = it.next(); + if (match.capturedEnd() >= posMin) + break; + } + int pos = match.capturedStart(); + int len = match.capturedLength(); + QString prefix = match.captured(1) + match.captured(3); bool hex = prefix.length() >= 2 && (prefix[1].toLower() == 'x'); bool octal = !hex && !prefix.isEmpty(); - const QString num = hex ? re.cap(2) : octal ? re.cap(4) : re.cap(5); + const QString num = hex ? match.captured(2) : octal ? match.captured(4) : match.captured(5); // parse value bool ok; @@ -8431,7 +8452,7 @@ bool FakeVimHandler::Private::changeNumberTextObject(int count) // convert hexadecimal number to upper-case if last letter was upper-case if (hex) { - const int lastLetter = num.lastIndexOf(QRegExp("[a-fA-F]")); + const int lastLetter = num.lastIndexOf(QRegularExpression("[a-fA-F]")); if (lastLetter != -1 && num[lastLetter].isUpper()) repl = repl.toUpper(); } @@ -8760,9 +8781,9 @@ void FakeVimHandler::handleReplay(const QString &keys) void FakeVimHandler::handleInput(const QString &keys) { - Inputs inputs(keys); + const Inputs inputs(keys); d->enterFakeVim(); - foreach (const Input &input, inputs) + for (const Input &input : inputs) d->handleKey(input); d->leaveFakeVim(); } |