aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/silversearcher
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2023-06-01 21:04:18 +0200
committerJarek Kobus <jaroslaw.kobus@qt.io>2023-06-02 11:51:08 +0000
commit64d209c24bb618fee5e0d4ba427d656c3b71e5ff (patch)
tree0a71134886b3360009d00732b3d8878ab551a74b /src/plugins/silversearcher
parent8da3575d7290be5002f06a363a622fd4ba70b803 (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.cpp147
-rw-r--r--src/plugins/silversearcher/silversearcherparser.cpp31
-rw-r--r--src/plugins/silversearcher/silversearcherparser.h15
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 &parameters)
-{
- 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 &parameters)
{
- 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> &regExp) {
+ 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> &regExp)
+SearchResultItems parse(const QFuture<void> &future, const QString &input,
+ const std::optional<QRegularExpression> &regExp, 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> &regExp)
{
- 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> &regExp = {});
+Utils::SearchResultItems parse(const QFuture<void> &future, const QString &input,
+ const std::optional<QRegularExpression> &regExp,
+ Utils::FilePath *lastFilePath);
Utils::SearchResultItems parse(const QString &input,
const std::optional<QRegularExpression> &regExp = {});