SpotlightLocatorFilter: Reimplement matchers()

Change-Id: I6ce29929516dee3b23b67f0cc07dce16ae7ad49d
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Jarek Kobus
2023-04-19 23:31:19 +02:00
parent f44641bec7
commit 27f62806ca
2 changed files with 88 additions and 0 deletions

View File

@@ -6,7 +6,10 @@
#include "../coreplugintr.h"
#include "../messagemanager.h"
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
#include <utils/asynctask.h>
#include <utils/commandline.h>
#include <utils/environment.h>
#include <utils/fancylineedit.h>
@@ -233,6 +236,89 @@ SpotlightLocatorFilter::SpotlightLocatorFilter()
reset();
}
static void matches(QPromise<void> &promise, const LocatorStorage &storage,
const CommandLine &command)
{
// If search string contains spaces, treat them as wildcard '*' and search in full path
const QString wildcardInput = QDir::fromNativeSeparators(storage.input()).replace(' ', '*');
const Link inputLink = Link::fromString(wildcardInput, true);
const QString newInput = inputLink.targetFilePath.toString();
const QRegularExpression regExp = ILocatorFilter::createRegExp(newInput);
if (!regExp.isValid())
return;
const bool hasPathSeparator = newInput.contains('/') || newInput.contains('*');
LocatorFileCache::MatchedEntries entries = {};
QEventLoop loop;
QtcProcess process;
process.setCommand(command);
process.setEnvironment(Environment::systemEnvironment()); // TODO: Is it needed?
QObject::connect(&process, &QtcProcess::readyReadStandardOutput, &process,
[&, entriesPtr = &entries] {
QString output = process.readAllStandardOutput();
output.replace("\r\n", "\n");
const QStringList items = output.split('\n');
const FilePaths filePaths = Utils::transform(items, &FilePath::fromUserInput);
LocatorFileCache::processFilePaths(promise.future(), filePaths, hasPathSeparator, regExp,
inputLink, entriesPtr);
if (promise.isCanceled())
loop.exit();
});
QObject::connect(&process, &QtcProcess::done, &process, [&] {
if (process.result() != ProcessResult::FinishedWithSuccess) {
MessageManager::writeFlashing(Tr::tr("Locator: Error occurred when running \"%1\".")
.arg(command.executable().toUserOutput()));
}
loop.exit();
});
QFutureWatcher<void> watcher;
watcher.setFuture(promise.future());
QObject::connect(&watcher, &QFutureWatcherBase::canceled, &watcher, [&loop] { loop.exit(); });
if (promise.isCanceled())
return;
process.start();
loop.exec();
for (auto &entry : entries) {
if (promise.isCanceled())
return;
if (entry.size() < 1000)
Utils::sort(entry, LocatorFilterEntry::compareLexigraphically);
}
if (promise.isCanceled())
return;
storage.reportOutput(std::accumulate(std::begin(entries), std::end(entries),
LocatorFilterEntries()));
}
LocatorMatcherTasks SpotlightLocatorFilter::matchers()
{
using namespace Tasking;
TreeStorage<LocatorStorage> storage;
const auto onSetup = [storage, command = m_command, insensArgs = m_arguments,
sensArgs = m_caseSensitiveArguments](AsyncTask<void> &async) {
const Link link = Link::fromString(storage->input(), true);
const FilePath input = link.targetFilePath;
if (input.isEmpty())
return TaskAction::StopWithDone;
// only pass the file name part to allow searches like "somepath/*foo"
const std::unique_ptr<MacroExpander> expander(createMacroExpander(input.fileName()));
const QString args = caseSensitivity(input.toString()) == Qt::CaseInsensitive
? insensArgs : sensArgs;
const CommandLine cmd(FilePath::fromString(command), expander->expand(args),
CommandLine::Raw);
async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer());
async.setConcurrentCallData(matches, *storage, cmd);
return TaskAction::Continue;
};
return {{Async<void>(onSetup), storage}};
}
void SpotlightLocatorFilter::prepareSearch(const QString &entry)
{
Link link = Utils::Link::fromString(entry, true);

View File

@@ -10,6 +10,7 @@
namespace Core {
namespace Internal {
// TODO: Don't derive from BaseFileFilter, flatten the hierarchy
class SpotlightLocatorFilter : public BaseFileFilter
{
Q_OBJECT
@@ -26,6 +27,7 @@ protected:
void restoreState(const QJsonObject &obj) final;
private:
LocatorMatcherTasks matchers() final;
void reset();
QString m_command;