diff options
author | Jarek Kobus <jaroslaw.kobus@qt.io> | 2023-06-01 21:04:18 +0200 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@qt.io> | 2023-06-02 11:51:08 +0000 |
commit | 64d209c24bb618fee5e0d4ba427d656c3b71e5ff (patch) | |
tree | 0a71134886b3360009d00732b3d8878ab551a74b /src/plugins/silversearcher | |
parent | 8da3575d7290be5002f06a363a622fd4ba70b803 (diff) |
SilverSearcher: Reuse searchInProcessOutput()
Change-Id: Ifc28a88c7bd0de94ea78c5f3eaaa2179b0aee600
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'src/plugins/silversearcher')
-rw-r--r-- | src/plugins/silversearcher/findinfilessilversearcher.cpp | 147 | ||||
-rw-r--r-- | src/plugins/silversearcher/silversearcherparser.cpp | 31 | ||||
-rw-r--r-- | src/plugins/silversearcher/silversearcherparser.h | 15 |
3 files changed, 58 insertions, 135 deletions
diff --git a/src/plugins/silversearcher/findinfilessilversearcher.cpp b/src/plugins/silversearcher/findinfilessilversearcher.cpp index 313d23eda2..6cf428bb64 100644 --- a/src/plugins/silversearcher/findinfilessilversearcher.cpp +++ b/src/plugins/silversearcher/findinfilessilversearcher.cpp @@ -59,114 +59,51 @@ static bool isSilverSearcherAvailable() && silverSearcherProcess.cleanedStdOut().contains("ag version"); } -static std::optional<QRegularExpression> regExpFromParameters(const FileFindParameters ¶meters) -{ - if (!(parameters.flags & FindRegularExpression)) - return {}; - - const QRegularExpression::PatternOptions patternOptions - = (parameters.flags & FindCaseSensitively) - ? QRegularExpression::NoPatternOption - : QRegularExpression::CaseInsensitiveOption; - QRegularExpression regExp; - regExp.setPattern(parameters.text); - regExp.setPatternOptions(patternOptions); - return regExp; -} - static void runSilverSeacher(QPromise<SearchResultItems> &promise, const FileFindParameters ¶meters) { - const FilePath directory = FilePath::fromUserInput(parameters.additionalParameters.toString()); - QStringList arguments = {"--parallel", "--ackmate"}; - - if (parameters.flags & FindCaseSensitively) - arguments << "-s"; - else - arguments << "-i"; - - if (parameters.flags & FindWholeWords) - arguments << "-w"; - - if (!(parameters.flags & FindRegularExpression)) - arguments << "-Q"; - - for (const QString &filter : std::as_const(parameters.exclusionFilters)) - arguments << "--ignore" << filter; - - QString nameFiltersAsRegExp; - for (const QString &filter : std::as_const(parameters.nameFilters)) - nameFiltersAsRegExp += QString("(%1)|").arg(convertWildcardToRegex(filter)); - nameFiltersAsRegExp.remove(nameFiltersAsRegExp.length() - 1, 1); - - arguments << "-G" << nameFiltersAsRegExp; - - const SilverSearcherSearchOptions params = parameters.searchEngineParameters - .value<SilverSearcherSearchOptions>(); - if (!params.searchOptions.isEmpty()) - arguments << params.searchOptions.split(' '); - - arguments << "--" << parameters.text << directory.normalizedPathName().toString(); - - QEventLoop loop; - - Process process; - process.setCommand({"ag", arguments}); - ParserState parserState; - const std::optional<QRegularExpression> regExp = regExpFromParameters(parameters); - QStringList outputBuffer; - // The states transition exactly in this order: - enum State { BelowLimit, AboveLimit, Paused, Resumed }; - State state = BelowLimit; - process.setStdOutCallback([&process, &loop, &promise, &state, &outputBuffer, &parserState, - regExp](const QString &output) { - if (promise.isCanceled()) { - process.close(); - loop.quit(); - return; - } - // The SearchResultWidget is going to pause the search anyway, so start buffering - // the output. - if (state == AboveLimit || state == Paused) { - outputBuffer.append(output); - } else { - SilverSearcher::parse(promise, output, &parserState, regExp); - if (state == BelowLimit && parserState.m_reportedResultsCount > 200000) - state = AboveLimit; - } - }); - QObject::connect(&process, &Process::done, &loop, [&loop, &promise, &state] { - if (state == BelowLimit || state == Resumed || promise.isCanceled()) - loop.quit(); - }); - - process.start(); - if (process.state() == QProcess::NotRunning) - return; - - QFutureWatcher<void> watcher; - QFuture<void> future(promise.future()); - QObject::connect(&watcher, &QFutureWatcherBase::canceled, &loop, [&process, &loop] { - process.close(); - loop.quit(); - }); - QObject::connect(&watcher, &QFutureWatcherBase::paused, &loop, [&state] { state = Paused; }); - QObject::connect(&watcher, &QFutureWatcherBase::resumed, &loop, - [&process, &loop, &promise, &state, &outputBuffer, &parserState, regExp] { - state = Resumed; - for (const QString &output : outputBuffer) { - if (promise.isCanceled()) { - process.close(); - loop.quit(); - } - SilverSearcher::parse(promise, output, &parserState, regExp); - } - outputBuffer.clear(); - if (process.state() == QProcess::NotRunning) - loop.quit(); - }); - watcher.setFuture(future); - loop.exec(QEventLoop::ExcludeUserInputEvents); + const auto setupProcess = [parameters](Process &process) { + const FilePath directory + = FilePath::fromUserInput(parameters.additionalParameters.toString()); + QStringList arguments = {"--parallel", "--ackmate"}; + + if (parameters.flags & FindCaseSensitively) + arguments << "-s"; + else + arguments << "-i"; + + if (parameters.flags & FindWholeWords) + arguments << "-w"; + + if (!(parameters.flags & FindRegularExpression)) + arguments << "-Q"; + + for (const QString &filter : std::as_const(parameters.exclusionFilters)) + arguments << "--ignore" << filter; + + QString nameFiltersAsRegExp; + for (const QString &filter : std::as_const(parameters.nameFilters)) + nameFiltersAsRegExp += QString("(%1)|").arg(convertWildcardToRegex(filter)); + nameFiltersAsRegExp.remove(nameFiltersAsRegExp.length() - 1, 1); + + arguments << "-G" << nameFiltersAsRegExp; + + const SilverSearcherSearchOptions params = parameters.searchEngineParameters + .value<SilverSearcherSearchOptions>(); + if (!params.searchOptions.isEmpty()) + arguments << params.searchOptions.split(' '); + + arguments << "--" << parameters.text << directory.normalizedPathName().toString(); + process.setCommand({"ag", arguments}); + }; + + FilePath lastFilePath; + const auto outputParser = [&lastFilePath](const QFuture<void> &future, const QString &input, + const std::optional<QRegularExpression> ®Exp) { + return SilverSearcher::parse(future, input, regExp, &lastFilePath); + }; + + TextEditor::searchInProcessOutput(promise, parameters, setupProcess, outputParser); } } // namespace diff --git a/src/plugins/silversearcher/silversearcherparser.cpp b/src/plugins/silversearcher/silversearcherparser.cpp index 9cdf5211a6..1a2f5e55e8 100644 --- a/src/plugins/silversearcher/silversearcherparser.cpp +++ b/src/plugins/silversearcher/silversearcherparser.cpp @@ -3,8 +3,6 @@ #include "silversearcherparser.h" -#include <QFuture> - using namespace Utils; namespace SilverSearcher { @@ -96,28 +94,28 @@ static bool parseLineHits(QStringView *remainingInput, QList<QPair<int, int>> *h return true; } -void parse(QPromise<SearchResultItems> &promise, const QString &input, - ParserState *parserState, const std::optional<QRegularExpression> ®Exp) +SearchResultItems parse(const QFuture<void> &future, const QString &input, + const std::optional<QRegularExpression> ®Exp, FilePath *lastFilePath) { - QTC_ASSERT(parserState, return); + QTC_ASSERT(lastFilePath, return {}); SearchResultItems items; QStringView remainingInput(input); while (true) { - if (promise.isCanceled()) - return; + if (future.isCanceled()) + return {}; if (remainingInput.isEmpty()) break; const QStringView filePathLine = nextLine(&remainingInput); if (filePathLine.isEmpty()) { - parserState->m_lastFilePath = {}; // Clear the parser state + *lastFilePath = {}; // Clear the parser state continue; } if (filePathLine.startsWith(':')) - parserState->m_lastFilePath = FilePath::fromPathPart(filePathLine.mid(1)); + *lastFilePath = FilePath::fromPathPart(filePathLine.mid(1)); while (true) { QStringView hitLine = nextLine(&remainingInput); @@ -133,7 +131,7 @@ void parse(QPromise<SearchResultItems> &promise, const QString &input, break; SearchResultItem item; - item.setFilePath(parserState->m_lastFilePath); + item.setFilePath(*lastFilePath); item.setDisplayText(hitLine.toString()); item.setUseTextEditorFont(true); for (const QPair<int, int> &hit : hits) { @@ -145,20 +143,15 @@ void parse(QPromise<SearchResultItems> &promise, const QString &input, } } } - if (!items.isEmpty()) - promise.addResult(items); - - parserState->m_reportedResultsCount += items.count(); + return items; } SearchResultItems parse(const QString &input, const std::optional<QRegularExpression> ®Exp) { - QPromise<SearchResultItems> promise; + QPromise<void> promise; promise.start(); - ParserState dummy; - SilverSearcher::parse(promise, input, &dummy, regExp); - promise.finish(); - return promise.future().resultCount() ? promise.future().result() : SearchResultItems(); + FilePath dummy; + return SilverSearcher::parse(promise.future(), input, regExp, &dummy); } } // namespace SilverSearcher diff --git a/src/plugins/silversearcher/silversearcherparser.h b/src/plugins/silversearcher/silversearcherparser.h index 1cc5ccb773..67b3e124f4 100644 --- a/src/plugins/silversearcher/silversearcherparser.h +++ b/src/plugins/silversearcher/silversearcherparser.h @@ -5,23 +5,16 @@ #include <utils/searchresultitem.h> -#include <QPromise> +#include <QFuture> #include <QRegularExpression> namespace Utils { class FilePath; } namespace SilverSearcher { -class ParserState -{ -public: - Utils::FilePath m_lastFilePath; - int m_reportedResultsCount = 0; -}; - -void parse(QPromise<Utils::SearchResultItems> &promise, const QString &input, - ParserState *parserState = nullptr, - const std::optional<QRegularExpression> ®Exp = {}); +Utils::SearchResultItems parse(const QFuture<void> &future, const QString &input, + const std::optional<QRegularExpression> ®Exp, + Utils::FilePath *lastFilePath); Utils::SearchResultItems parse(const QString &input, const std::optional<QRegularExpression> ®Exp = {}); |