forked from qt-creator/qt-creator
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:
@@ -6,7 +6,10 @@
|
|||||||
#include "../coreplugintr.h"
|
#include "../coreplugintr.h"
|
||||||
#include "../messagemanager.h"
|
#include "../messagemanager.h"
|
||||||
|
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/asynctask.h>
|
||||||
#include <utils/commandline.h>
|
#include <utils/commandline.h>
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
#include <utils/fancylineedit.h>
|
#include <utils/fancylineedit.h>
|
||||||
@@ -233,6 +236,89 @@ SpotlightLocatorFilter::SpotlightLocatorFilter()
|
|||||||
reset();
|
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)
|
void SpotlightLocatorFilter::prepareSearch(const QString &entry)
|
||||||
{
|
{
|
||||||
Link link = Utils::Link::fromString(entry, true);
|
Link link = Utils::Link::fromString(entry, true);
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
// TODO: Don't derive from BaseFileFilter, flatten the hierarchy
|
||||||
class SpotlightLocatorFilter : public BaseFileFilter
|
class SpotlightLocatorFilter : public BaseFileFilter
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -26,6 +27,7 @@ protected:
|
|||||||
void restoreState(const QJsonObject &obj) final;
|
void restoreState(const QJsonObject &obj) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
LocatorMatcherTasks matchers() final;
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
QString m_command;
|
QString m_command;
|
||||||
|
Reference in New Issue
Block a user