File indexing completed on 2024-05-05 09:46:22
0001 /* 0002 * SPDX-FileCopyrightText: 2008 Sebastian Kügler <sebas@kde.org> 0003 * SPDX-FileCopyrightText: 2017 Kai Uwe Broulik <kde@privat.broulik.de> 0004 * SPDX-FileCopyrightText: 2020 Alexander Lohnau <alexander.lohnau@gmx.de> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "katesessions.h" 0010 0011 #include <QCollator> 0012 #include <QDir> 0013 #include <QFileInfo> 0014 #include <QStandardPaths> 0015 0016 #include <KDirWatch> 0017 #include <KFuzzyMatcher> 0018 #include <KLocalizedString> 0019 #include <KNotificationJobUiDelegate> 0020 0021 #include <KIO/CommandLauncherJob> 0022 0023 K_PLUGIN_CLASS_WITH_JSON(KateSessions, "plasma-runner-katesessions.json") 0024 0025 KateSessions::KateSessions(QObject *parent, const KPluginMetaData &metaData) 0026 : AbstractRunner(parent, metaData) 0027 { 0028 addSyntax(QStringLiteral("kate :q:"), i18n("Finds Kate sessions matching :q:.")); 0029 addSyntax(QStringLiteral("kate"), i18n("Lists all the Kate editor sessions in your account.")); 0030 0031 // Initialize watchers and sessions 0032 setTriggerWords({m_triggerWord}); 0033 } 0034 0035 void KateSessions::match(RunnerContext &context) 0036 { 0037 QString term = context.query(); 0038 bool listAll = false; 0039 if (term.trimmed().compare(m_triggerWord, Qt::CaseInsensitive) == 0) { 0040 listAll = true; 0041 term.clear(); 0042 } else if (term.startsWith(m_triggerWord + ' ')) { 0043 term.remove(m_triggerWord, Qt::CaseInsensitive); 0044 term = std::move(term).trimmed(); 0045 } else if (!context.singleRunnerQueryMode()) { 0046 // Prevent results for queries like "katee" 0047 return; 0048 } 0049 0050 QList<QueryMatch> matches; 0051 int maxScore = 0; 0052 0053 for (int i = 0, count = m_model->rowCount(); i < count; ++i) { 0054 // Does the query match exactly? 0055 // no query = perfect match => list everything 0056 QString session = m_model->index(i).data(ProfilesModel::NameRole).toString(); 0057 if (listAll || session.compare(term, Qt::CaseInsensitive) == 0) { 0058 QueryMatch match(this); 0059 match.setCategoryRelevance(QueryMatch::CategoryRelevance::Highest); 0060 match.setRelevance(session.compare(term, Qt::CaseInsensitive) == 0 ? 1 : 0.8); 0061 match.setIconName(m_triggerWord); 0062 match.setData(session); 0063 match.setText(session); 0064 match.setSubtext(i18n("Open Kate Session")); 0065 context.addMatch(match); 0066 } else { 0067 // Do fuzzy matching 0068 const auto res = KFuzzyMatcher::match(term, session); 0069 if (res.matched) { 0070 QueryMatch match(this); 0071 match.setRelevance(res.score); // store the score here for now 0072 match.setIconName(m_triggerWord); 0073 match.setData(session); 0074 match.setText(session); 0075 match.setSubtext(i18n("Open Kate Session")); 0076 matches.push_back(match); 0077 maxScore = std::max(res.score, maxScore); 0078 } 0079 } 0080 } 0081 0082 auto calculate_relevance = [maxScore](double score) { 0083 return score / maxScore; 0084 }; 0085 for (auto &match : matches) { 0086 match.setRelevance(calculate_relevance(match.relevance())); 0087 } 0088 context.addMatches(matches); 0089 } 0090 0091 void KateSessions::run(const RunnerContext & /*context*/, const QueryMatch &match) 0092 { 0093 m_model->openProfile(match.data().toString()); 0094 } 0095 0096 void KateSessions::init() 0097 { 0098 // Only create this in the correct thread. Inside we use KDirWatch which is thread sensitive. 0099 m_model = new ProfilesModel(this); 0100 m_model->setAppName(m_triggerWord); 0101 } 0102 0103 #include "katesessions.moc"