diff --git a/autotests/src/codecompletiontestmodels.h b/autotests/src/codecompletiontestmodels.h --- a/autotests/src/codecompletiontestmodels.h +++ b/autotests/src/codecompletiontestmodels.h @@ -26,6 +26,8 @@ #include #include +#include + using namespace KTextEditor; class CustomRangeModel : public CodeCompletionTestModel, public CodeCompletionModelControllerInterface @@ -55,8 +57,8 @@ { Q_UNUSED(view); Q_UNUSED(range); - static const QRegExp allowedText("^\\$?(\\w*)"); - return !allowedText.exactMatch(currentCompletion); + static const QRegularExpression allowedText("^\\$?(\\w*)$"); + return !allowedText.match(currentCompletion).hasMatch(); } }; @@ -73,8 +75,8 @@ { Q_UNUSED(view); Q_UNUSED(range); - static const QRegExp allowedText("^([\\w-]*)"); - return !allowedText.exactMatch(currentCompletion); + static const QRegularExpression allowedText("^([\\w-]*)"); + return !allowedText.match(currentCompletion).hasMatch(); } }; diff --git a/autotests/src/vimode/emulatedcommandbar.cpp b/autotests/src/vimode/emulatedcommandbar.cpp --- a/autotests/src/vimode/emulatedcommandbar.cpp +++ b/autotests/src/vimode/emulatedcommandbar.cpp @@ -3349,10 +3349,11 @@ // Be a bit vague about the actual contents due to e.g. localization. // TODO - see if we can insist that en_US is available on the Kate Jenkins server and // insist that we use it ... ? - QRegExp numReplacementsMessageRegex("^.*(\\d+).*(\\d+).*$"); - QVERIFY(numReplacementsMessageRegex.exactMatch(commandMessageResponseText)); - const QString actualNumReplacementsAsString = numReplacementsMessageRegex.cap(1); - const QString actualAcrossNumLinesAsString = numReplacementsMessageRegex.cap(2); + static const QRegularExpression numReplacementsMessageRegex("^.*(\\d+).*(\\d+).*$"); + const auto match = numReplacementsMessageRegex.match(commandMessageResponseText); + QVERIFY(match.hasMatch()); + const QString actualNumReplacementsAsString = match.captured(1); + const QString actualAcrossNumLinesAsString = match.captured(2); QCOMPARE(actualNumReplacementsAsString, expectedNumReplacementsAsString); QCOMPARE(actualAcrossNumLinesAsString, expectedAcrossNumLinesAsString); } diff --git a/autotests/src/vimode/fakecodecompletiontestmodel.cpp b/autotests/src/vimode/fakecodecompletiontestmodel.cpp --- a/autotests/src/vimode/fakecodecompletiontestmodel.cpp +++ b/autotests/src/vimode/fakecodecompletiontestmodel.cpp @@ -24,6 +24,7 @@ #include #include "base.h" #include "fakecodecompletiontestmodel.h" +#include using namespace KTextEditor; @@ -120,10 +121,11 @@ // The code for a function call to a function taking no arguments. const QString justFunctionName = textToInsert.left(textToInsert.indexOf("(")); - QRegExp whitespaceThenOpeningBracket("^\\s*(\\()"); + static const QRegularExpression whitespaceThenOpeningBracket("^\\s*(\\()"); + const QRegularExpressionMatch match = whitespaceThenOpeningBracket.match(textAfterCursor); int openingBracketPos = -1; - if (textAfterCursor.contains(whitespaceThenOpeningBracket)) { - openingBracketPos = whitespaceThenOpeningBracket.pos(1) + word.start().column() + justFunctionName.length() + 1 + lengthStillToRemove; + if (match.hasMatch()) { + openingBracketPos = match.capturedStart(1) + word.start().column() + justFunctionName.length() + 1 + lengthStillToRemove; } const bool mergeOpenBracketWithExisting = (openingBracketPos != -1) && !endedWithSemiColon; // Add the function name, for now: we don't yet know if we'll be adding the "()", too. diff --git a/src/document/katedocument.cpp b/src/document/katedocument.cpp --- a/src/document/katedocument.cpp +++ b/src/document/katedocument.cpp @@ -4673,9 +4673,9 @@ bool found = false; foreach (const QString &pattern, wildcards) { - QRegExp wildcard(pattern, Qt::CaseSensitive, QRegExp::Wildcard); + QRegularExpression wildcard(QLatin1Char('^') + QRegularExpression::wildcardToRegularExpression(pattern) + QLatin1Char('$')); - found = wildcard.exactMatch(nameOfFile); + found = wildcard.match(nameOfFile).hasMatch(); if (found) { break; } diff --git a/src/script/katescriptmanager.cpp b/src/script/katescriptmanager.cpp --- a/src/script/katescriptmanager.cpp +++ b/src/script/katescriptmanager.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -308,22 +309,17 @@ bool KateScriptManager::exec(KTextEditor::View *view, const QString &_cmd, QString &errorMsg, const KTextEditor::Range &) { - QStringList args(_cmd.split(QRegExp(QLatin1String("\\s+")), QString::SkipEmptyParts)); - QString cmd(args.first()); - args.removeFirst(); + Q_UNUSED(view) - if (!view) { - errorMsg = i18n("Could not access view"); - return false; - } + QVector args = _cmd.splitRef(QRegularExpression(QLatin1String("\\s+")), QString::SkipEmptyParts); + const QString cmd = args.first().toString(); if (cmd == QLatin1String("reload-scripts")) { reload(); return true; - } else { - errorMsg = i18n("Command not found: %1", cmd); - return false; } + + return false; } bool KateScriptManager::help(KTextEditor::View *view, const QString &cmd, QString &msg) @@ -333,9 +329,8 @@ if (cmd == QLatin1String("reload-scripts")) { msg = i18n("Reload all JavaScript files (indenters, command line scripts, etc)."); return true; - } else { - msg = i18n("Command not found: %1", cmd); - return false; } + + return false; } diff --git a/src/view/kateviewhelpers.cpp b/src/view/kateviewhelpers.cpp --- a/src/view/kateviewhelpers.cpp +++ b/src/view/kateviewhelpers.cpp @@ -50,7 +50,7 @@ #include #include -#include +#include #include #include #include @@ -1113,16 +1113,17 @@ QString KateCmdLineEdit::helptext(const QPoint &) const { - QString beg = QStringLiteral("
Help: "); - QString mid = QStringLiteral("
"); - QString end = QStringLiteral("
"); + const QString beg = QStringLiteral("
Help: "); + const QString mid = QStringLiteral("
"); + const QString end = QStringLiteral("
"); - QString t = text(); - QRegExp re(QLatin1String("\\s*help\\s+(.*)")); - if (re.indexIn(t) > -1) { + const QString t = text(); + static const QRegularExpression re(QLatin1String("\\s*help\\s+(.*)")); + auto match = re.match(t); + if (match.hasMatch()) { QString s; // get help for command - QString name = re.cap(1); + const QString name = match.captured(1); if (name == QLatin1String("list")) { return beg + i18n("Available Commands") + mid + KateCmd::self()->commandList().join(QLatin1Char(' ')) @@ -1224,7 +1225,7 @@ m_msgMode = true; // the following commands changes the focus themselves, so bar should be hidden before execution. - if (QRegExp(QLatin1String("buffer|b|new|vnew|bp|bprev|bn|bnext|bf|bfirst|bl|blast|edit|e")).exactMatch(cmd.split(QLatin1Char(' ')).at(0))) { + if (QRegularExpression(QLatin1String("^(buffer|b|new|vnew|bp|bprev|bn|bnext|bf|bfirst|bl|blast|edit|e)$")).match(cmd.split(QLatin1Char(' ')).at(0)).hasMatch()) { emit hideRequested(); } @@ -1273,7 +1274,7 @@ m_cmdend = 0; // the following commands change the focus themselves - if (!QRegExp(QLatin1String("buffer|b|new|vnew|bp|bprev|bn|bnext|bf|bfirst|bl|blast|edit|e")).exactMatch(cmd.split(QLatin1Char(' ')).at(0))) { + if (!QRegularExpression(QLatin1String("^(buffer|b|new|vnew|bp|bprev|bn|bnext|bf|bfirst|bl|blast|edit|e)$")).match(cmd.split(QLatin1Char(' ')).at(0)).hasMatch()) { m_view->setFocus(); } @@ -1413,9 +1414,10 @@ if (! s.isEmpty()) { // Select the argument part of the command, so that it is easy to overwrite setText(s); - static QRegExp reCmd = QRegExp(QLatin1String(".*[\\w\\-]+(?:[^a-zA-Z0-9_-]|:\\w+)(.*)")); - if (reCmd.indexIn(text()) == 0) { - setSelection(text().length() - reCmd.cap(1).length(), reCmd.cap(1).length()); + static const QRegularExpression reCmd(QLatin1String("^[\\w\\-]+(?:[^a-zA-Z0-9_-]|:\\w+)(.*)")); + const auto match = reCmd.match(text()); + if (match.hasMatch()) { + setSelection(text().length() - match.capturedLength(1), match.capturedLength(1)); } } } diff --git a/src/vimode/appcommands.h b/src/vimode/appcommands.h --- a/src/vimode/appcommands.h +++ b/src/vimode/appcommands.h @@ -23,6 +23,7 @@ #include #include +#include namespace KTextEditor { class MainWindow; @@ -67,17 +68,17 @@ void quit(); private: - QRegExp re_write; - QRegExp re_close; - QRegExp re_quit; - QRegExp re_exit; - QRegExp re_edit; - QRegExp re_tabedit; - QRegExp re_new; - QRegExp re_split; - QRegExp re_vsplit; - QRegExp re_vclose; - QRegExp re_only; + const QRegularExpression re_write; + const QRegularExpression re_close; + const QRegularExpression re_quit; + const QRegularExpression re_exit; + const QRegularExpression re_edit; + const QRegularExpression re_tabedit; + const QRegularExpression re_new; + const QRegularExpression re_split; + const QRegularExpression re_vsplit; + const QRegularExpression re_vclose; + const QRegularExpression re_only; }; class BufferCommands : public KTextEditor::Command diff --git a/src/vimode/appcommands.cpp b/src/vimode/appcommands.cpp --- a/src/vimode/appcommands.cpp +++ b/src/vimode/appcommands.cpp @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -41,18 +42,18 @@ , QStringLiteral("vnew"), QStringLiteral("e"), QStringLiteral("edit"), QStringLiteral("enew"), QStringLiteral("sp"), QStringLiteral("split"), QStringLiteral("vs") , QStringLiteral("vsplit"), QStringLiteral("only"), QStringLiteral("tabe"), QStringLiteral("tabedit"), QStringLiteral("tabnew"), QStringLiteral("bd") , QStringLiteral("bdelete"), QStringLiteral("tabc"), QStringLiteral("tabclose"), QStringLiteral("clo"), QStringLiteral("close") }) + , re_write(QStringLiteral("^w(a)?$")) + , re_close(QStringLiteral("^bd(elete)?|tabc(lose)?$")) + , re_quit(QStringLiteral("^(w)?q(a|all)?(!)?$")) + , re_exit(QStringLiteral("^x(a)?$")) + , re_edit(QStringLiteral("^e(dit)?|tabe(dit)?|tabnew$")) + , re_tabedit(QStringLiteral("^tabe(dit)?|tabnew$")) + , re_new(QStringLiteral("^(v)?new$")) + , re_split(QStringLiteral("^sp(lit)?$")) + , re_vsplit(QStringLiteral("^vs(plit)?$")) + , re_vclose(QStringLiteral("^clo(se)?$")) + , re_only(QStringLiteral("^on(ly)?$")) { - re_write.setPattern(QStringLiteral("w(a)?")); - re_close.setPattern(QStringLiteral("bd(elete)?|tabc(lose)?")); - re_quit.setPattern(QStringLiteral("(w)?q(a|all)?(!)?")); - re_exit.setPattern(QStringLiteral("x(a)?")); - re_edit.setPattern(QStringLiteral("e(dit)?|tabe(dit)?|tabnew")); - re_tabedit.setPattern(QStringLiteral("tabe(dit)?|tabnew")); - re_new.setPattern(QStringLiteral("(v)?new")); - re_split.setPattern(QStringLiteral("sp(lit)?")); - re_vsplit.setPattern(QStringLiteral("vs(plit)?")); - re_vclose.setPattern(QStringLiteral("clo(se)?")); - re_only.setPattern(QStringLiteral("on(ly)?")); } AppCommands::~AppCommands() @@ -62,14 +63,15 @@ bool AppCommands::exec(KTextEditor::View *view, const QString &cmd, QString &msg, const KTextEditor::Range &) { - QStringList args(cmd.split(QRegExp(QLatin1String("\\s+")), QString::SkipEmptyParts)) ; + QStringList args(cmd.split(QRegularExpression(QLatin1String("\\s+")), QString::SkipEmptyParts)) ; QString command(args.takeFirst()); KTextEditor::MainWindow *mainWin = view->mainWindow(); KTextEditor::Application *app = KTextEditor::Editor::instance()->application(); - if (re_write.exactMatch(command)) { //TODO: handle writing to specific file - if (!re_write.cap(1).isEmpty()) { // [a]ll + QRegularExpressionMatch match; + if ((match = re_write.match(command)).hasMatch()) { //TODO: handle writing to specific file + if (!match.captured(1).isEmpty()) { // [a]ll Q_FOREACH(KTextEditor::Document *doc, app->documents()) { doc->save(); } @@ -80,12 +82,12 @@ } } // Other buffer commands are implemented by the KateFileTree plugin - else if (re_close.exactMatch(command)) { + else if ((match = re_close.match(command)).hasMatch()) { QTimer::singleShot(0, [app, view](){ app->closeDocument(view->document()); }); - } else if (re_quit.exactMatch(command)) { - const bool save = !re_quit.cap(1).isEmpty(); // :[w]q - const bool allDocuments = !re_quit.cap(2).isEmpty(); // :q[all] - const bool doNotPromptForSave = !re_quit.cap(3).isEmpty(); // :q[!] + } else if ((match = re_quit.match(command)).hasMatch()) { + const bool save = !match.captured(1).isEmpty(); // :[w]q + const bool allDocuments = !match.captured(2).isEmpty(); // :q[all] + const bool doNotPromptForSave = !match.captured(3).isEmpty(); // :q[!] if (allDocuments) { if (save) { @@ -122,8 +124,8 @@ } } } - } else if (re_exit.exactMatch(command)) { - if (!re_exit.cap(1).isEmpty()) { // a[ll] + } else if ((match = re_exit.match(command)).hasMatch()) { + if (!match.captured(1).isEmpty()) { // a[ll] Q_FOREACH(KTextEditor::Document *doc, app->documents()) { doc->save(); } @@ -139,10 +141,10 @@ QTimer::singleShot(0, this, SLOT(quit())); } } - } else if (re_edit.exactMatch(command)) { + } else if ((match = re_edit.match(command)).hasMatch()) { QString argument = args.join(QLatin1Char(' ')); if (argument.isEmpty() || argument == QLatin1String("!")) { - if (re_tabedit.exactMatch(command)) { + if ((match = re_tabedit.match(command)).hasMatch()) { if (auto doc = app->openUrl(QUrl())) { QTimer::singleShot(0, [mainWin, doc](){ mainWin->activateView(doc); }); } @@ -177,22 +179,22 @@ } // splitView() orientations are reversed from the usual editor convention. // 'vsplit' and 'vnew' use Qt::Horizontal to match vi and the Kate UI actions. - } else if (re_new.exactMatch(command)) { - if (re_new.cap(1) == QLatin1String("v")) { // vertical split + } else if ((match = re_new.match(command)).hasMatch()) { + if (match.captured(1) == QLatin1String("v")) { // vertical split mainWin->splitView(Qt::Horizontal); } else { // horizontal split mainWin->splitView(Qt::Vertical); } mainWin->openUrl(QUrl()); } else if (command == QLatin1String("enew")) { mainWin->openUrl(QUrl()); - } else if (re_split.exactMatch(command)) { + } else if ((match = re_split.match(command)).hasMatch()) { mainWin->splitView(Qt::Vertical); // see above - } else if (re_vsplit.exactMatch(command)) { + } else if ((match = re_vsplit.match(command)).hasMatch()) { mainWin->splitView(Qt::Horizontal); - } else if (re_vclose.exactMatch(command)) { + } else if ((match = re_vclose.match(command)).hasMatch()) { QTimer::singleShot(0, this, SLOT(closeCurrentSplitView())); - } else if (re_only.exactMatch(command)) { + } else if ((match = re_only.match(command)).hasMatch()) { QTimer::singleShot(0, this, SLOT(closeOtherSplitViews())); } @@ -203,7 +205,7 @@ { Q_UNUSED(view); - if (re_write.exactMatch(cmd)) { + if (re_write.match(cmd).hasMatch()) { msg = i18n("

w/wa — write document(s) to disk

" "

Usage: w[a]

" "

Writes the current document(s) to disk. " @@ -213,7 +215,7 @@ "

If no file name is associated with the document, " "a file dialog will be shown.

"); return true; - } else if (re_quit.exactMatch(cmd)) { + } else if (re_quit.match(cmd).hasMatch()) { msg = i18n("

q/qa/wq/wqa — [write and] quit

" "

Usage: [w]q[a]

" "

Quits the application. If w is prepended, it also writes" @@ -227,7 +229,7 @@ "If no file name is associated with the document and it should be written to disk, " "a file dialog will be shown.

"); return true; - } else if (re_exit.exactMatch(cmd)) { + } else if (re_exit.match(cmd).hasMatch()) { msg = i18n("

x/xa — write and quit

" "

Usage: x[a]

" "

Saves document(s) and quits (exits). This command " @@ -240,31 +242,31 @@ "

Unlike the 'w' commands, this command only writes the document if it is modified." "

"); return true; - } else if (re_split.exactMatch(cmd)) { + } else if (re_split.match(cmd).hasMatch()) { msg = i18n("

sp,split— Split horizontally the current view into two

" "

Usage: sp[lit]

" "

The result is two views on the same document.

"); return true; - } else if (re_vsplit.exactMatch(cmd)) { + } else if (re_vsplit.match(cmd).hasMatch()) { msg = i18n("

vs,vsplit— Split vertically the current view into two

" "

Usage: vs[plit]

" "

The result is two views on the same document.

"); return true; - } else if (re_vclose.exactMatch(cmd)) { + } else if (re_vclose.match(cmd).hasMatch()) { msg = i18n("

clo[se]— Close the current view

" "

Usage: clo[se]

" "

After executing it, the current view will be closed.

"); return true; - } else if (re_new.exactMatch(cmd)) { + } else if (re_new.match(cmd).hasMatch()) { msg = i18n("

[v]new — split view and create new document

" "

Usage: [v]new

" "

Splits the current view and opens a new document in the new view." " This command can be called in two ways:
" " new — splits the view horizontally and opens a new document.
" " vnew — splits the view vertically and opens a new document.
" "

"); return true; - } else if (re_edit.exactMatch(cmd)) { + } else if (re_edit.match(cmd).hasMatch()) { msg = i18n("

e[dit] — reload current document

" "

Usage: e[dit]

" "

Starts editing the current document again. This is useful to re-edit" diff --git a/src/vimode/cmds.cpp b/src/vimode/cmds.cpp --- a/src/vimode/cmds.cpp +++ b/src/vimode/cmds.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include using namespace KateVi; @@ -58,7 +58,7 @@ } //create a list of args - QStringList args(_cmd.split(QRegExp(QLatin1String("\\s+")), QString::SkipEmptyParts)); + QStringList args(_cmd.split(QRegularExpression(QLatin1String("\\s+")), QString::SkipEmptyParts)); QString cmd(args.takeFirst()); // ALL commands that takes no arguments. @@ -106,10 +106,11 @@ range.end().line()), 0)); } - QRegExp number(QLatin1String("^(\\d+)$")); + static const QRegularExpression number(QLatin1String("^(\\d+)$")); for (int i = 0; i < args.count(); i++) { - if (number.indexIn(args.at(i)) != -1) { - count += number.cap().toInt() - 1; + auto match = number.match(args.at(i)); + if (match.hasMatch()) { + count += match.captured(0).toInt() - 1; } QChar r = args.at(i).at(0); diff --git a/src/vimode/completionreplayer.cpp b/src/vimode/completionreplayer.cpp --- a/src/vimode/completionreplayer.cpp +++ b/src/vimode/completionreplayer.cpp @@ -28,6 +28,7 @@ #include "lastchangerecorder.h" #include +#include using namespace KateVi; @@ -144,10 +145,11 @@ { KTextEditor::DocumentPrivate *doc = m_viInputModeManager->view()->doc(); const QString lineAfterCursor = doc->text(KTextEditor::Range(startPos, KTextEditor::Cursor(startPos.line(), doc->lineLength(startPos.line())))); - QRegExp whitespaceThenOpeningBracket(QLatin1String("^\\s*(\\()")); + static const QRegularExpression whitespaceThenOpeningBracket(QLatin1String("^\\s*(\\()")); + QRegularExpressionMatch match = whitespaceThenOpeningBracket.match(lineAfterCursor); int nextMergableBracketAfterCursorPos = -1; - if (lineAfterCursor.contains(whitespaceThenOpeningBracket)) { - nextMergableBracketAfterCursorPos = whitespaceThenOpeningBracket.pos(1); + if (match.hasMatch()) { + nextMergableBracketAfterCursorPos = match.capturedStart(1); } return nextMergableBracketAfterCursorPos; } diff --git a/src/vimode/emulatedcommandbar/commandmode.cpp b/src/vimode/emulatedcommandbar/commandmode.cpp --- a/src/vimode/emulatedcommandbar/commandmode.cpp +++ b/src/vimode/emulatedcommandbar/commandmode.cpp @@ -37,6 +37,7 @@ #include #include +#include #include using namespace KateVi; @@ -223,7 +224,8 @@ } // the following commands change the focus themselves - if (!QRegExp(QLatin1String("buffer|b|new|vnew|bp|bprev|tabp|tabprev|bn|bnext|tabn|tabnext|bf|bfirst|tabf|tabfirst|bl|blast|tabl|tablast|e|edit|tabe|tabedit|tabnew")).exactMatch(cmd.split(QLatin1Char(' ')).at(0))) { + static const QRegularExpression reCmds(QLatin1String("^(buffer|b|new|vnew|bp|bprev|tabp|tabprev|bn|bnext|tabn|tabnext|bf|bfirst|tabf|tabfirst|bl|blast|tabl|tablast|e|edit|tabe|tabedit|tabnew)$")); + if (!reCmds.match(cmd.split(QLatin1Char(' ')).at(0)).hasMatch()) { view()->setFocus(); } diff --git a/src/vimode/emulatedcommandbar/completer.cpp b/src/vimode/emulatedcommandbar/completer.cpp --- a/src/vimode/emulatedcommandbar/completer.cpp +++ b/src/vimode/emulatedcommandbar/completer.cpp @@ -29,6 +29,7 @@ #include #include #include +#include namespace { @@ -207,17 +208,20 @@ CompletionStartParams Completer::activateWordFromDocumentCompletion() { - QRegExp wordRegEx(QLatin1String("\\w{1,}")); + static const QRegularExpression wordRegEx(QLatin1String("\\w{1,}")); + QRegularExpressionMatch match; + QStringList foundWords; // Narrow the range of lines we search around the cursor so that we don't die on huge files. const int startLine = qMax(0, m_view->cursorPosition().line() - 4096); const int endLine = qMin(m_view->document()->lines(), m_view->cursorPosition().line() + 4096); for (int lineNum = startLine; lineNum < endLine; lineNum++) { - const QString line = m_view->document()->line(lineNum); int wordSearchBeginPos = 0; - while (wordRegEx.indexIn(line, wordSearchBeginPos) != -1) { - const QString foundWord = wordRegEx.cap(0); + const QString line = m_view->document()->line(lineNum); + int wordSearchBeginPos = 0; + while ((match = wordRegEx.match(line, wordSearchBeginPos)).hasMatch()) { + const QString foundWord = match.captured(); foundWords << foundWord; - wordSearchBeginPos = wordRegEx.indexIn(line, wordSearchBeginPos) + wordRegEx.matchedLength(); + wordSearchBeginPos = match.capturedEnd(); } } foundWords = QSet::fromList(foundWords).toList();