diff options
Diffstat (limited to 'source/kde/kde/patch/kate')
5 files changed, 0 insertions, 1239 deletions
diff --git a/source/kde/kde/patch/kate/361dd43e42994829dbdb35e78fb7698d27cbb0e2.patch b/source/kde/kde/patch/kate/361dd43e42994829dbdb35e78fb7698d27cbb0e2.patch deleted file mode 100644 index 4f7237aaa..000000000 --- a/source/kde/kde/patch/kate/361dd43e42994829dbdb35e78fb7698d27cbb0e2.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 361dd43e42994829dbdb35e78fb7698d27cbb0e2 Mon Sep 17 00:00:00 2001 -From: Mark Nauwelaerts <mark.nauwelaerts@gmail.com> -Date: Mon, 13 Dec 2021 20:52:57 +0100 -Subject: [PATCH] lspclient: consider some additional server capabilities - ---- - addons/lspclient/lspclientprotocol.h | 14 +++++++++++++- - addons/lspclient/lspclientserver.cpp | 9 ++++++++- - addons/lspclient/lspclientservermanager.cpp | 2 +- - 3 files changed, 22 insertions(+), 3 deletions(-) - -diff --git a/addons/lspclient/lspclientprotocol.h b/addons/lspclient/lspclientprotocol.h -index 0fb7f4485..9de0ec511 100644 ---- a/addons/lspclient/lspclientprotocol.h -+++ b/addons/lspclient/lspclientprotocol.h -@@ -21,6 +21,8 @@ - #include <KTextEditor/Cursor> - #include <KTextEditor/Range> - -+#include <optional> -+ - // Following types roughly follow the types/interfaces as defined in LSP protocol spec - // although some deviation may arise where it has been deemed useful - // Moreover, to avoid introducing a custom 'optional' type, absence of an optional -@@ -51,6 +53,16 @@ struct LSPResponseError { - - enum class LSPDocumentSyncKind { None = 0, Full = 1, Incremental = 2 }; - -+struct LSPSaveOptions { -+ bool includeText = false; -+}; -+ -+// only used parts for now -+struct LSPTextDocumentSyncOptions { -+ LSPDocumentSyncKind change = LSPDocumentSyncKind::None; -+ std::optional<LSPSaveOptions> save; -+}; -+ - struct LSPCompletionOptions { - bool provider = false; - bool resolveProvider = false; -@@ -81,7 +93,7 @@ struct LSPWorkspaceFoldersServerCapabilities { - }; - - struct LSPServerCapabilities { -- LSPDocumentSyncKind textDocumentSync = LSPDocumentSyncKind::None; -+ LSPTextDocumentSyncOptions textDocumentSync; - bool hoverProvider = false; - LSPCompletionOptions completionProvider; - LSPSignatureHelpOptions signatureHelpProvider; -diff --git a/addons/lspclient/lspclientserver.cpp b/addons/lspclient/lspclientserver.cpp -index 8739d46c9..a7094fde2 100644 ---- a/addons/lspclient/lspclientserver.cpp -+++ b/addons/lspclient/lspclientserver.cpp -@@ -344,8 +344,15 @@ static void from_json(LSPServerCapabilities &caps, const QJsonObject &json) - }; - - auto sync = json.value(QStringLiteral("textDocumentSync")); -- caps.textDocumentSync = static_cast<LSPDocumentSyncKind>( -+ caps.textDocumentSync.change = static_cast<LSPDocumentSyncKind>( - (sync.isObject() ? sync.toObject().value(QStringLiteral("change")) : sync).toInt(static_cast<int>(LSPDocumentSyncKind::None))); -+ if (sync.isObject()) { -+ auto syncObject = sync.toObject(); -+ auto save = syncObject.value(QStringLiteral("save")); -+ if (save.isObject() || save.toBool()) { -+ caps.textDocumentSync.save = {save.toObject().value(QStringLiteral("includeText")).toBool()}; -+ } -+ } - caps.hoverProvider = toBoolOrObject(json.value(QStringLiteral("hoverProvider"))); - from_json(caps.completionProvider, json.value(QStringLiteral("completionProvider"))); - from_json(caps.signatureHelpProvider, json.value(QStringLiteral("signatureHelpProvider"))); -diff --git a/addons/lspclient/lspclientservermanager.cpp b/addons/lspclient/lspclientservermanager.cpp -index 1fbcf928f..1e03801ea 100644 ---- a/addons/lspclient/lspclientservermanager.cpp -+++ b/addons/lspclient/lspclientservermanager.cpp -@@ -931,7 +931,7 @@ private: - auto it = m_docs.find(doc); - if (it != m_docs.end() && it->server) { - const auto &caps = it->server->capabilities(); -- if (caps.textDocumentSync == LSPDocumentSyncKind::Incremental) { -+ if (caps.textDocumentSync.change == LSPDocumentSyncKind::Incremental) { - return &(*it); - } - } --- -GitLab - diff --git a/source/kde/kde/patch/kate/6fc3bf6e5bd540e842e32c4a959c2158c8573be5.patch b/source/kde/kde/patch/kate/6fc3bf6e5bd540e842e32c4a959c2158c8573be5.patch deleted file mode 100644 index cdbde70ff..000000000 --- a/source/kde/kde/patch/kate/6fc3bf6e5bd540e842e32c4a959c2158c8573be5.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 6fc3bf6e5bd540e842e32c4a959c2158c8573be5 Mon Sep 17 00:00:00 2001 -From: Mark Nauwelaerts <mark.nauwelaerts@gmail.com> -Date: Mon, 13 Dec 2021 21:36:50 +0100 -Subject: [PATCH] lspclient: send didSave notification if so requested - ---- - addons/lspclient/lspclientserver.cpp | 7 +++++-- - addons/lspclient/lspclientservermanager.cpp | 15 +++++++++++++++ - 2 files changed, 20 insertions(+), 2 deletions(-) - -diff --git a/addons/lspclient/lspclientserver.cpp b/addons/lspclient/lspclientserver.cpp -index a7094fde2..9fb5844cd 100644 ---- a/addons/lspclient/lspclientserver.cpp -+++ b/addons/lspclient/lspclientserver.cpp -@@ -1255,7 +1255,8 @@ private: - {QStringLiteral("documentSymbol"), QJsonObject{{QStringLiteral("hierarchicalDocumentSymbolSupport"), true}} }, - {QStringLiteral("publishDiagnostics"), QJsonObject{{QStringLiteral("relatedInformation"), true}}}, - {QStringLiteral("codeAction"), codeAction}, -- {QStringLiteral("semanticTokens"), semanticTokens} -+ {QStringLiteral("semanticTokens"), semanticTokens}, -+ {QStringLiteral("synchronization"), QJsonObject{{QStringLiteral("didSave"), true}}}, - }, - }, - {QStringLiteral("window"), -@@ -1475,7 +1476,9 @@ public: - void didSave(const QUrl &document, const QString &text) - { - auto params = textDocumentParams(document); -- params[QStringLiteral("text")] = text; -+ if (!text.isNull()) { -+ params[QStringLiteral("text")] = text; -+ } - send(init_request(QStringLiteral("textDocument/didSave"), params)); - } - -diff --git a/addons/lspclient/lspclientservermanager.cpp b/addons/lspclient/lspclientservermanager.cpp -index 1e03801ea..551926e23 100644 ---- a/addons/lspclient/lspclientservermanager.cpp -+++ b/addons/lspclient/lspclientservermanager.cpp -@@ -833,6 +833,7 @@ private: - connect(doc, &KTextEditor::Document::aboutToClose, this, &self_type::untrack, Qt::UniqueConnection); - connect(doc, &KTextEditor::Document::destroyed, this, &self_type::untrack, Qt::UniqueConnection); - connect(doc, &KTextEditor::Document::textChanged, this, &self_type::onTextChanged, Qt::UniqueConnection); -+ connect(doc, &KTextEditor::Document::documentSavedOrUploaded, this, &self_type::onDocumentSaved, Qt::UniqueConnection); - // in case of incremental change - connect(doc, &KTextEditor::Document::textInserted, this, &self_type::onTextInserted, Qt::UniqueConnection); - connect(doc, &KTextEditor::Document::textRemoved, this, &self_type::onTextRemoved, Qt::UniqueConnection); -@@ -976,6 +977,20 @@ private: - } - } - -+ void onDocumentSaved(KTextEditor::Document *doc, bool saveAs) -+ { -+ if (!saveAs) { -+ auto it = m_docs.find(doc); -+ if (it != m_docs.end() && it->server) { -+ auto server = it->server; -+ const auto &saveOptions = server->capabilities().textDocumentSync.save; -+ if (saveOptions) { -+ server->didSave(doc->url(), saveOptions->includeText ? doc->text() : QString()); -+ } -+ } -+ } -+ } -+ - void onMessage(bool isLog, const LSPLogMessageParams ¶ms) - { - // determine server description --- -GitLab - diff --git a/source/kde/kde/patch/kate/7e08a58fb50d28ba96aedd5f5cd79a9479b4a0ad.patch b/source/kde/kde/patch/kate/7e08a58fb50d28ba96aedd5f5cd79a9479b4a0ad.patch deleted file mode 100644 index 456f33618..000000000 --- a/source/kde/kde/patch/kate/7e08a58fb50d28ba96aedd5f5cd79a9479b4a0ad.patch +++ /dev/null @@ -1,918 +0,0 @@ -From 7e08a58fb50d28ba96aedd5f5cd79a9479b4a0ad Mon Sep 17 00:00:00 2001 -From: Christoph Cullmann <cullmann@kde.org> -Date: Mon, 24 Jan 2022 19:07:37 +0000 -Subject: [PATCH] improve QProcess handling - -ensure we take executables from PATH for execution instead possibly from current working directory -or the working directory set for the QProcess ---- - addons/compiler-explorer/compiledbreader.cpp | 4 +- - addons/externaltools/katetoolrunner.cpp | 9 +++- - addons/gdbplugin/debugview.cpp | 17 +++++++- - addons/git-blame/commitfilesview.cpp | 17 +++++--- - addons/git-blame/kategitblameplugin.cpp | 8 +++- - addons/kate-ctags/gotosymbolmodel.cpp | 15 +++++-- - addons/project/comparebranchesview.cpp | 4 +- - addons/project/filehistorywidget.cpp | 14 +++++-- - addons/project/git/gitutils.cpp | 41 +++++++++++++++---- - addons/project/gitwidget.cpp | 19 +++++++-- - addons/project/kateprojectindex.cpp | 9 +++- - .../kateprojectinfoviewcodeanalysis.cpp | 9 +++- - addons/project/kateprojectworker.cpp | 32 +++++++++++---- - addons/project/stashdialog.cpp | 20 ++++----- - addons/project/stashdialog.h | 2 +- - addons/replicode/replicodeview.cpp | 9 ++++ - addons/xmlcheck/plugin_katexmlcheck.cpp | 8 ++++ - kate/katefileactions.cpp | 17 ++++---- - kate/katefileactions.h | 4 +- - kate/katemwmodonhddialog.cpp | 6 ++- - kate/katemwmodonhddialog.h | 1 + - kate/kateviewspace.cpp | 7 +++- - shared/gitprocess.h | 16 +++++++- - 23 files changed, 217 insertions(+), 71 deletions(-) - -diff --git a/addons/compiler-explorer/compiledbreader.cpp b/addons/compiler-explorer/compiledbreader.cpp -index 74e83638e..ab9ebc483 100644 ---- a/addons/compiler-explorer/compiledbreader.cpp -+++ b/addons/compiler-explorer/compiledbreader.cpp -@@ -21,7 +21,9 @@ std::optional<QString> getDotGitPath(const QString &repo) - { - /* This call is intentionally blocking because we need git path for everything else */ - QProcess git; -- setupGitProcess(git, repo, {QStringLiteral("rev-parse"), QStringLiteral("--absolute-git-dir")}); -+ if (!setupGitProcess(git, repo, {QStringLiteral("rev-parse"), QStringLiteral("--absolute-git-dir")})) { -+ return std::nullopt; -+ } - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) { -diff --git a/addons/externaltools/katetoolrunner.cpp b/addons/externaltools/katetoolrunner.cpp -index 10a5d7226..e14940ad7 100644 ---- a/addons/externaltools/katetoolrunner.cpp -+++ b/addons/externaltools/katetoolrunner.cpp -@@ -14,6 +14,7 @@ - #include <KTextEditor/View> - #include <QFileInfo> - #include <QRegularExpression> -+#include <QStandardPaths> - - KateToolRunner::KateToolRunner(std::unique_ptr<KateExternalTool> tool, KTextEditor::View *view, QObject *parent) - : QObject(parent) -@@ -40,6 +41,12 @@ KateExternalTool *KateToolRunner::tool() const - - void KateToolRunner::run() - { -+ // always only execute the tool from PATH -+ const auto fullExecutable = QStandardPaths::findExecutable(m_tool->executable); -+ if (fullExecutable.isEmpty()) { -+ return; -+ } -+ - if (!m_tool->workingDir.isEmpty()) { - m_process->setWorkingDirectory(m_tool->workingDir); - } else if (m_view) { -@@ -72,7 +79,7 @@ void KateToolRunner::run() - }); - - const QStringList args = KShell::splitArgs(m_tool->arguments); -- m_process->start(m_tool->executable, args); -+ m_process->start(fullExecutable, args); - } - - void KateToolRunner::waitForFinished() -diff --git a/addons/gdbplugin/debugview.cpp b/addons/gdbplugin/debugview.cpp -index 9505daa25..d8c868d7a 100644 ---- a/addons/gdbplugin/debugview.cpp -+++ b/addons/gdbplugin/debugview.cpp -@@ -12,7 +12,9 @@ - #include "debugview.h" - - #include <QFile> -+#include <QFileInfo> - #include <QRegularExpression> -+#include <QStandardPaths> - #include <QTimer> - - #include <KLocalizedString> -@@ -48,7 +50,20 @@ void DebugView::runDebugger(const GDBTargetConf &conf, const QStringList &ioFifo - if (conf.executable.isEmpty()) { - return; - } -+ - m_targetConf = conf; -+ -+ // no chance if no debugger configured -+ if (m_targetConf.gdbCmd.isEmpty()) { -+ return; -+ } -+ -+ // only run debugger from PATH or the absolute executable path we specified -+ const auto fullExecutable = QFileInfo(m_targetConf.gdbCmd).isAbsolute() ? m_targetConf.gdbCmd : QStandardPaths::findExecutable(m_targetConf.gdbCmd); -+ if (fullExecutable.isEmpty()) { -+ return; -+ } -+ - if (ioFifos.size() == 3) { - m_ioPipeString = QStringLiteral("< %1 1> %2 2> %3").arg(ioFifos[0], ioFifos[1], ioFifos[2]); - } -@@ -69,7 +84,7 @@ void DebugView::runDebugger(const GDBTargetConf &conf, const QStringList &ioFifo - - connect(&m_debugProcess, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &DebugView::slotDebugFinished); - -- m_debugProcess.start(m_targetConf.gdbCmd, QStringList()); -+ m_debugProcess.start(fullExecutable, QStringList()); - - m_nextCommands << QStringLiteral("set pagination off"); - m_state = ready; -diff --git a/addons/git-blame/commitfilesview.cpp b/addons/git-blame/commitfilesview.cpp -index 26e484a4a..667b423b2 100644 ---- a/addons/git-blame/commitfilesview.cpp -+++ b/addons/git-blame/commitfilesview.cpp -@@ -263,7 +263,9 @@ static void createFileTree(QStandardItem *parent, const QString &basePath, const - static std::optional<QString> getGitCmdOutput(const QString &workDir, const QStringList &args) - { - QProcess git; -- setupGitProcess(git, workDir, args); -+ if (!setupGitProcess(git, workDir, args)) { -+ return {}; -+ } - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) { -@@ -365,9 +367,12 @@ void CommitDiffTreeView::openCommit(const QString &hash, const QString &filePath - m_commitHash = hash; - - QProcess *git = new QProcess(this); -- setupGitProcess(*git, -- QFileInfo(filePath).absolutePath(), -- {QStringLiteral("show"), hash, QStringLiteral("--numstat"), QStringLiteral("--pretty=oneline"), QStringLiteral("-z")}); -+ if (!setupGitProcess(*git, -+ QFileInfo(filePath).absolutePath(), -+ {QStringLiteral("show"), hash, QStringLiteral("--numstat"), QStringLiteral("--pretty=oneline"), QStringLiteral("-z")})) { -+ delete git; -+ return; -+ } - connect(git, &QProcess::finished, this, [this, git, filePath](int e, QProcess::ExitStatus s) { - git->deleteLater(); - if (e != 0 || s != QProcess::NormalExit) { -@@ -440,7 +445,9 @@ void CommitDiffTreeView::showDiff(const QModelIndex &idx) - { - const QString file = idx.data(FileItem::Path).toString(); - QProcess git; -- setupGitProcess(git, m_gitDir, {QStringLiteral("show"), m_commitHash, QStringLiteral("--"), file}); -+ if (!setupGitProcess(git, m_gitDir, {QStringLiteral("show"), m_commitHash, QStringLiteral("--"), file})) { -+ return; -+ } - git.start(QProcess::ReadOnly); - - if (git.waitForStarted() && git.waitForFinished(-1)) { -diff --git a/addons/git-blame/kategitblameplugin.cpp b/addons/git-blame/kategitblameplugin.cpp -index d0354cc75..ae0f8c106 100644 ---- a/addons/git-blame/kategitblameplugin.cpp -+++ b/addons/git-blame/kategitblameplugin.cpp -@@ -255,7 +255,9 @@ void KateGitBlamePluginView::startBlameProcess(const QUrl &url) - QDir dir{url.toLocalFile()}; - dir.cdUp(); - -- setupGitProcess(m_blameInfoProc, dir.absolutePath(), {QStringLiteral("blame"), QStringLiteral("-p"), QStringLiteral("./%1").arg(fileName)}); -+ if (!setupGitProcess(m_blameInfoProc, dir.absolutePath(), {QStringLiteral("blame"), QStringLiteral("-p"), QStringLiteral("./%1").arg(fileName)})) { -+ return; -+ } - m_blameInfoProc.start(QIODevice::ReadOnly); - m_blameUrl = url; - } -@@ -270,7 +272,9 @@ void KateGitBlamePluginView::startShowProcess(const QUrl &url, const QString &ha - QDir dir{url.toLocalFile()}; - dir.cdUp(); - -- setupGitProcess(m_showProc, dir.absolutePath(), {QStringLiteral("show"), hash, QStringLiteral("--numstat")}); -+ if (!setupGitProcess(m_showProc, dir.absolutePath(), {QStringLiteral("show"), hash, QStringLiteral("--numstat")})) { -+ return; -+ } - m_showProc.start(QIODevice::ReadOnly); - } - -diff --git a/addons/kate-ctags/gotosymbolmodel.cpp b/addons/kate-ctags/gotosymbolmodel.cpp -index 6c547e379..0c116090f 100644 ---- a/addons/kate-ctags/gotosymbolmodel.cpp -+++ b/addons/kate-ctags/gotosymbolmodel.cpp -@@ -8,6 +8,7 @@ - #include <KLocalizedString> - #include <QDebug> - #include <QProcess> -+#include <QStandardPaths> - - GotoSymbolModel::GotoSymbolModel(QObject *parent) - : QAbstractTableModel(parent) -@@ -58,16 +59,24 @@ void GotoSymbolModel::refresh(const QString &filePath) - m_rows.clear(); - endResetModel(); - -+ // only use ctags from PATH -+ static const auto fullExecutablePath = QStandardPaths::findExecutable(QStringLiteral("ctags")); -+ if (fullExecutablePath.isEmpty()) { -+ beginResetModel(); -+ m_rows.append(SymbolItem{i18n("CTags executable not found."), -1, QIcon()}); -+ endResetModel(); -+ return; -+ } -+ - QProcess p; -- p.start(QStringLiteral("ctags"), {QStringLiteral("-x"), QStringLiteral("--_xformat=%{name}%{signature}\t%{kind}\t%{line}"), filePath}); -+ p.start(fullExecutablePath, {QStringLiteral("-x"), QStringLiteral("--_xformat=%{name}%{signature}\t%{kind}\t%{line}"), filePath}); - - QByteArray out; - if (p.waitForFinished()) { - out = p.readAllStandardOutput(); - } else { -- qWarning() << "Ctags failed"; - beginResetModel(); -- m_rows.append(SymbolItem{i18n("CTags executable not found."), -1, QIcon()}); -+ m_rows.append(SymbolItem{i18n("CTags executable failed to execute."), -1, QIcon()}); - endResetModel(); - return; - } -diff --git a/addons/project/comparebranchesview.cpp b/addons/project/comparebranchesview.cpp -index 48d1d2633..7cf585f66 100644 ---- a/addons/project/comparebranchesview.cpp -+++ b/addons/project/comparebranchesview.cpp -@@ -158,7 +158,9 @@ void CompareBranchesView::showDiff(const QModelIndex &idx) - { - auto file = idx.data(Qt::UserRole).toString().remove(m_gitDir + QLatin1Char('/')); - QProcess git; -- setupGitProcess(git, m_gitDir, {QStringLiteral("diff"), QStringLiteral("%1...%2").arg(m_fromBr).arg(m_toBr), QStringLiteral("--"), file}); -+ if (!setupGitProcess(git, m_gitDir, {QStringLiteral("diff"), QStringLiteral("%1...%2").arg(m_fromBr).arg(m_toBr), QStringLiteral("--"), file})) { -+ return; -+ } - git.start(QProcess::ReadOnly); - - if (git.waitForStarted() && git.waitForFinished(-1)) { -diff --git a/addons/project/filehistorywidget.cpp b/addons/project/filehistorywidget.cpp -index 626016a6b..14857e178 100644 ---- a/addons/project/filehistorywidget.cpp -+++ b/addons/project/filehistorywidget.cpp -@@ -231,9 +231,12 @@ FileHistoryWidget::~FileHistoryWidget() - // git log --format=%H%n%aN%n%aE%n%at%n%ct%n%P%n%B --author-date-order - void FileHistoryWidget::getFileHistory(const QString &file) - { -- setupGitProcess(m_git, -- QFileInfo(file).absolutePath(), -- {QStringLiteral("log"), QStringLiteral("--format=%H%n%aN%n%aE%n%at%n%ct%n%P%n%B"), QStringLiteral("-z"), file}); -+ if (!setupGitProcess(m_git, -+ QFileInfo(file).absolutePath(), -+ {QStringLiteral("log"), QStringLiteral("--format=%H%n%aN%n%aE%n%at%n%ct%n%P%n%B"), QStringLiteral("-z"), file})) { -+ Q_EMIT errorMessage(i18n("Failed to get file history: git executable not found in PATH"), true); -+ return; -+ } - - connect(&m_git, &QProcess::readyReadStandardOutput, this, [this] { - auto commits = parseCommits(m_git.readAllStandardOutput().split(0x00)); -@@ -258,7 +261,10 @@ void FileHistoryWidget::itemClicked(const QModelIndex &idx) - - const auto commit = idx.data(CommitListModel::CommitRole).value<Commit>(); - -- setupGitProcess(git, fi.absolutePath(), {QStringLiteral("show"), QString::fromUtf8(commit.hash), QStringLiteral("--"), m_file}); -+ if (!setupGitProcess(git, fi.absolutePath(), {QStringLiteral("show"), QString::fromUtf8(commit.hash), QStringLiteral("--"), m_file})) { -+ return; -+ } -+ - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) { -diff --git a/addons/project/git/gitutils.cpp b/addons/project/git/gitutils.cpp -index ea8dd8823..8b494c16f 100644 ---- a/addons/project/git/gitutils.cpp -+++ b/addons/project/git/gitutils.cpp -@@ -15,7 +15,10 @@ - bool GitUtils::isGitRepo(const QString &repo) - { - QProcess git; -- setupGitProcess(git, repo, {QStringLiteral("rev-parse"), QStringLiteral("--is-inside-work-tree")}); -+ if (!setupGitProcess(git, repo, {QStringLiteral("rev-parse"), QStringLiteral("--is-inside-work-tree")})) { -+ return false; -+ } -+ - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - return git.readAll().trimmed() == "true"; -@@ -27,7 +30,10 @@ std::optional<QString> GitUtils::getDotGitPath(const QString &repo) - { - /* This call is intentionally blocking because we need git path for everything else */ - QProcess git; -- setupGitProcess(git, repo, {QStringLiteral("rev-parse"), QStringLiteral("--absolute-git-dir")}); -+ if (!setupGitProcess(git, repo, {QStringLiteral("rev-parse"), QStringLiteral("--absolute-git-dir")})) { -+ return std::nullopt; -+ } -+ - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) { -@@ -57,7 +63,10 @@ QString GitUtils::getCurrentBranchName(const QString &repo) - - for (int i = 0; i < 3; ++i) { - QProcess git; -- setupGitProcess(git, repo, argsList[i]); -+ if (!setupGitProcess(git, repo, argsList[i])) { -+ return QString(); -+ } -+ - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - if (git.exitStatus() == QProcess::NormalExit && git.exitCode() == 0) { -@@ -73,7 +82,10 @@ QString GitUtils::getCurrentBranchName(const QString &repo) - GitUtils::CheckoutResult GitUtils::checkoutBranch(const QString &repo, const QString &branch) - { - QProcess git; -- setupGitProcess(git, repo, {QStringLiteral("checkout"), branch}); -+ if (!setupGitProcess(git, repo, {QStringLiteral("checkout"), branch})) { -+ return CheckoutResult{}; -+ } -+ - git.start(QProcess::ReadOnly); - CheckoutResult res; - res.branch = branch; -@@ -91,7 +103,11 @@ GitUtils::CheckoutResult GitUtils::checkoutNewBranch(const QString &repo, const - if (!fromBranch.isEmpty()) { - args.append(fromBranch); - } -- setupGitProcess(git, repo, args); -+ -+ if (!setupGitProcess(git, repo, args)) { -+ return CheckoutResult{}; -+ } -+ - git.start(QProcess::ReadOnly); - CheckoutResult res; - res.branch = newBranch; -@@ -132,7 +148,10 @@ QVector<GitUtils::Branch> GitUtils::getAllBranchesAndTags(const QString &repo, R - args.append(QStringLiteral("--sort=-taggerdate")); - } - -- setupGitProcess(git, repo, args); -+ if (!setupGitProcess(git, repo, args)) { -+ return {}; -+ } -+ - git.start(QProcess::ReadOnly); - QVector<Branch> branches; - if (git.waitForStarted() && git.waitForFinished(-1)) { -@@ -166,7 +185,10 @@ std::pair<QString, QString> GitUtils::getLastCommitMessage(const QString &repo) - { - // git log -1 --pretty=%B - QProcess git; -- setupGitProcess(git, repo, {QStringLiteral("log"), QStringLiteral("-1"), QStringLiteral("--pretty=%B")}); -+ if (!setupGitProcess(git, repo, {QStringLiteral("log"), QStringLiteral("-1"), QStringLiteral("--pretty=%B")})) { -+ return {}; -+ } -+ - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - if (git.exitCode() != 0 || git.exitStatus() != QProcess::NormalExit) { -@@ -197,7 +219,10 @@ GitUtils::Result GitUtils::deleteBranches(const QStringList &branches, const QSt - args << branches; - - QProcess git; -- setupGitProcess(git, repo, args); -+ if (!setupGitProcess(git, repo, args)) { -+ return {}; -+ } -+ - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - QString out = QString::fromLatin1(git.readAllStandardError()) + QString::fromLatin1(git.readAllStandardOutput()); -diff --git a/addons/project/gitwidget.cpp b/addons/project/gitwidget.cpp -index 2b19781c0..77499dad8 100644 ---- a/addons/project/gitwidget.cpp -+++ b/addons/project/gitwidget.cpp -@@ -514,8 +514,9 @@ void GitWidget::launchExternalDiffTool(const QString &file, bool staged) - args.append(file); - - QProcess git; -- setupGitProcess(git, m_gitPath, args); -- git.startDetached(); -+ if (setupGitProcess(git, m_gitPath, args)) { -+ git.startDetached(); -+ } - } - - void GitWidget::commitChanges(const QString &msg, const QString &desc, bool signOff, bool amend) -@@ -745,7 +746,12 @@ void GitWidget::branchCompareFiles(const QString &from, const QString &to) - auto args = QStringList{QStringLiteral("diff"), QStringLiteral("%1...%2").arg(from).arg(to), QStringLiteral("--name-status")}; - - QProcess git; -- setupGitProcess(git, m_gitPath, args); -+ -+ // early out if we can't find git -+ if (!setupGitProcess(git, m_gitPath, args)) { -+ return; -+ } -+ - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) { -@@ -767,7 +773,12 @@ void GitWidget::branchCompareFiles(const QString &from, const QString &to) - - // get --num-stat - args = QStringList{QStringLiteral("diff"), QStringLiteral("%1...%2").arg(from).arg(to), QStringLiteral("--numstat"), QStringLiteral("-z")}; -- setupGitProcess(git, m_gitPath, args); -+ -+ // early out if we can't find git -+ if (!setupGitProcess(git, m_gitPath, args)) { -+ return; -+ } -+ - git.start(QProcess::ReadOnly); - if (git.waitForStarted() && git.waitForFinished(-1)) { - if (git.exitStatus() != QProcess::NormalExit || git.exitCode() != 0) { -diff --git a/addons/project/kateprojectindex.cpp b/addons/project/kateprojectindex.cpp -index a7d9ec9c1..9fc5b64cb 100644 ---- a/addons/project/kateprojectindex.cpp -+++ b/addons/project/kateprojectindex.cpp -@@ -9,6 +9,7 @@ - - #include <QDir> - #include <QProcess> -+#include <QStandardPaths> - - /** - * include ctags reading -@@ -73,6 +74,12 @@ void KateProjectIndex::loadCtags(const QStringList &files, const QVariantMap &ct - */ - m_ctagsIndexFile->close(); - -+ // only use ctags from PATH -+ static const auto fullExecutablePath = QStandardPaths::findExecutable(QStringLiteral("ctags")); -+ if (fullExecutablePath.isEmpty()) { -+ return; -+ } -+ - /** - * try to run ctags for all files in this project - * output to our ctags index file -@@ -85,7 +92,7 @@ void KateProjectIndex::loadCtags(const QStringList &files, const QVariantMap &ct - for (const QVariant &optVariant : opts) { - args << optVariant.toString(); - } -- ctags.start(QStringLiteral("ctags"), args); -+ ctags.start(fullExecutablePath, args); - if (!ctags.waitForStarted()) { - return; - } -diff --git a/addons/project/kateprojectinfoviewcodeanalysis.cpp b/addons/project/kateprojectinfoviewcodeanalysis.cpp -index 21cd26a84..23b82c45e 100644 ---- a/addons/project/kateprojectinfoviewcodeanalysis.cpp -+++ b/addons/project/kateprojectinfoviewcodeanalysis.cpp -@@ -13,6 +13,7 @@ - - #include <QFileInfo> - #include <QHBoxLayout> -+#include <QStandardPaths> - #include <QToolTip> - #include <QVBoxLayout> - -@@ -134,14 +135,18 @@ void KateProjectInfoViewCodeAnalysis::slotStartStopClicked() - connect(m_analyzer, &QProcess::readyRead, this, &KateProjectInfoViewCodeAnalysis::slotReadyRead); - connect(m_analyzer, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &KateProjectInfoViewCodeAnalysis::finished); - -- m_analyzer->start(m_analysisTool->path(), m_analysisTool->arguments()); -+ // ensure we only run the code analyzer from PATH -+ const QString fullExecutable = QStandardPaths::findExecutable(m_analysisTool->path()); -+ if (!fullExecutable.isEmpty()) { -+ m_analyzer->start(fullExecutable, m_analysisTool->arguments()); -+ } - - if (m_messageWidget) { - delete m_messageWidget; - m_messageWidget = nullptr; - } - -- if (!m_analyzer->waitForStarted()) { -+ if (fullExecutable.isEmpty() || !m_analyzer->waitForStarted()) { - m_messageWidget = new KMessageWidget(this); - m_messageWidget->setCloseButtonVisible(true); - m_messageWidget->setMessageType(KMessageWidget::Warning); -diff --git a/addons/project/kateprojectworker.cpp b/addons/project/kateprojectworker.cpp -index d1979d1ec..831dae89b 100644 ---- a/addons/project/kateprojectworker.cpp -+++ b/addons/project/kateprojectworker.cpp -@@ -18,6 +18,7 @@ - #include <QRegularExpression> - #include <QSet> - #include <QSettings> -+#include <QStandardPaths> - #include <QThread> - #include <QTime> - #include <QtConcurrent> -@@ -442,10 +443,12 @@ QVector<QString> KateProjectWorker::filesFromGit(const QDir &dir, bool recursive - - QVector<QString> KateProjectWorker::gitFiles(const QDir &dir, bool recursive, const QStringList &args) - { -+ QVector<QString> files; - QProcess git; -- setupGitProcess(git, dir.absolutePath(), args); -+ if (!setupGitProcess(git, dir.absolutePath(), args)) { -+ return files; -+ } - git.start(QProcess::ReadOnly); -- QVector<QString> files; - if (!git.waitForStarted() || !git.waitForFinished(-1)) { - return files; - } -@@ -466,13 +469,18 @@ QVector<QString> KateProjectWorker::gitFiles(const QDir &dir, bool recursive, co - - QVector<QString> KateProjectWorker::filesFromMercurial(const QDir &dir, bool recursive) - { -+ // only use version control from PATH - QVector<QString> files; -+ static const auto fullExecutablePath = QStandardPaths::findExecutable(QStringLiteral("hg")); -+ if (fullExecutablePath.isEmpty()) { -+ return files; -+ } - - QProcess hg; - hg.setWorkingDirectory(dir.absolutePath()); - QStringList args; - args << QStringLiteral("manifest") << QStringLiteral("."); -- hg.start(QStringLiteral("hg"), args, QProcess::ReadOnly); -+ hg.start(fullExecutablePath, args, QProcess::ReadOnly); - if (!hg.waitForStarted() || !hg.waitForFinished(-1)) { - return files; - } -@@ -493,7 +501,12 @@ QVector<QString> KateProjectWorker::filesFromMercurial(const QDir &dir, bool rec - - QVector<QString> KateProjectWorker::filesFromSubversion(const QDir &dir, bool recursive) - { -+ // only use version control from PATH - QVector<QString> files; -+ static const auto fullExecutablePath = QStandardPaths::findExecutable(QStringLiteral("svn")); -+ if (fullExecutablePath.isEmpty()) { -+ return files; -+ } - - QProcess svn; - svn.setWorkingDirectory(dir.absolutePath()); -@@ -504,7 +517,7 @@ QVector<QString> KateProjectWorker::filesFromSubversion(const QDir &dir, bool re - } else { - args << QStringLiteral("--depth=files"); - } -- svn.start(QStringLiteral("svn"), args, QProcess::ReadOnly); -+ svn.start(fullExecutablePath, args, QProcess::ReadOnly); - if (!svn.waitForStarted() || !svn.waitForFinished(-1)) { - return files; - } -@@ -555,18 +568,21 @@ QVector<QString> KateProjectWorker::filesFromSubversion(const QDir &dir, bool re - - QVector<QString> KateProjectWorker::filesFromDarcs(const QDir &dir, bool recursive) - { -+ // only use version control from PATH - QVector<QString> files; -+ static const auto fullExecutablePath = QStandardPaths::findExecutable(QStringLiteral("darcs")); -+ if (fullExecutablePath.isEmpty()) { -+ return files; -+ } - -- const QString cmd = QStringLiteral("darcs"); - QString root; -- - { - QProcess darcs; - darcs.setWorkingDirectory(dir.absolutePath()); - QStringList args; - args << QStringLiteral("list") << QStringLiteral("repo"); - -- darcs.start(cmd, args, QProcess::ReadOnly); -+ darcs.start(fullExecutablePath, args, QProcess::ReadOnly); - - if (!darcs.waitForStarted() || !darcs.waitForFinished(-1)) { - return files; -@@ -590,7 +606,7 @@ QVector<QString> KateProjectWorker::filesFromDarcs(const QDir &dir, bool recursi - darcs.setWorkingDirectory(dir.absolutePath()); - args << QStringLiteral("list") << QStringLiteral("files") << QStringLiteral("--no-directories") << QStringLiteral("--pending"); - -- darcs.start(cmd, args, QProcess::ReadOnly); -+ darcs.start(fullExecutablePath, args, QProcess::ReadOnly); - - if (!darcs.waitForStarted() || !darcs.waitForFinished(-1)) { - return files; -diff --git a/addons/project/stashdialog.cpp b/addons/project/stashdialog.cpp -index c623182a8..bddedf709 100644 ---- a/addons/project/stashdialog.cpp -+++ b/addons/project/stashdialog.cpp -@@ -32,6 +32,8 @@ - - #include <kfts_fuzzy_match.h> - -+#include <gitprocess.h> -+ - constexpr int StashIndexRole = Qt::UserRole + 2; - - class StashFilterModel final : public QSortFilterProxyModel -@@ -218,11 +220,10 @@ void StashDialog::slotReturnPressed() - hide(); - } - --QProcess *StashDialog::gitp() -+QProcess *StashDialog::gitp(const QStringList &arguments) - { - auto git = new QProcess(this); -- git->setProgram(QStringLiteral("git")); -- git->setWorkingDirectory(m_gitPath); -+ setupGitProcess(*git, m_gitPath, arguments); - return git; - } - -@@ -242,7 +243,7 @@ void StashDialog::stash(bool keepIndex, bool includeUntracked) - args.append(m_lineEdit.text()); - } - -- auto git = gitp(); -+ auto git = gitp(args); - connect(git, &QProcess::finished, this, [this, git](int exitCode, QProcess::ExitStatus es) { - if (es != QProcess::NormalExit || exitCode != 0) { - qWarning() << git->errorString(); -@@ -253,14 +254,12 @@ void StashDialog::stash(bool keepIndex, bool includeUntracked) - Q_EMIT done(); - git->deleteLater(); - }); -- git->setArguments(args); - git->start(QProcess::ReadOnly); - } - - void StashDialog::getStashList() - { -- auto git = gitp(); -- git->setArguments({QStringLiteral("stash"), QStringLiteral("list")}); -+ auto git = gitp({QStringLiteral("stash"), QStringLiteral("list")}); - git->start(QProcess::ReadOnly); - - QList<QByteArray> stashList; -@@ -293,11 +292,11 @@ void StashDialog::getStashList() - - void StashDialog::popStash(const QByteArray &index, const QString &command) - { -- auto git = gitp(); - QStringList args{QStringLiteral("stash"), command}; - if (!index.isEmpty()) { - args.append(QString::fromUtf8(index)); - } -+ auto git = gitp(args); - - connect(git, &QProcess::finished, this, [this, command, git](int exitCode, QProcess::ExitStatus es) { - if (es != QProcess::NormalExit || exitCode != 0) { -@@ -320,7 +319,6 @@ void StashDialog::popStash(const QByteArray &index, const QString &command) - Q_EMIT done(); - git->deleteLater(); - }); -- git->setArguments(args); - git->start(QProcess::ReadOnly); - } - -@@ -339,9 +337,8 @@ void StashDialog::showStash(const QByteArray &index) - if (index.isEmpty()) { - return; - } -- auto git = gitp(); - -- QStringList args{QStringLiteral("stash"), QStringLiteral("show"), QStringLiteral("-p"), QString::fromUtf8(index)}; -+ auto git = gitp({QStringLiteral("stash"), QStringLiteral("show"), QStringLiteral("-p"), QString::fromUtf8(index)}); - - connect(git, &QProcess::finished, this, [this, git](int exitCode, QProcess::ExitStatus es) { - if (es != QProcess::NormalExit || exitCode != 0) { -@@ -353,6 +350,5 @@ void StashDialog::showStash(const QByteArray &index) - git->deleteLater(); - }); - -- git->setArguments(args); - git->start(QProcess::ReadOnly); - } -diff --git a/addons/project/stashdialog.h b/addons/project/stashdialog.h -index a18d42ab9..417690757 100644 ---- a/addons/project/stashdialog.h -+++ b/addons/project/stashdialog.h -@@ -56,7 +56,7 @@ protected Q_SLOTS: - void slotReturnPressed() override; - - private: -- QProcess *gitp(); -+ QProcess *gitp(const QStringList &arguments); - void stash(bool keepIndex, bool includeUntracked); - void getStashList(); - void popStash(const QByteArray &index, const QString &command = QStringLiteral("pop")); -diff --git a/addons/replicode/replicodeview.cpp b/addons/replicode/replicodeview.cpp -index 0199f46ce..7f70ee1ea 100644 ---- a/addons/replicode/replicodeview.cpp -+++ b/addons/replicode/replicodeview.cpp -@@ -8,7 +8,9 @@ - - #include "replicodeconfig.h" - #include "replicodesettings.h" -+ - #include <QPushButton> -+#include <QStandardPaths> - #include <QTemporaryFile> - #include <QtGlobal> - -@@ -116,7 +118,14 @@ void ReplicodeView::runReplicode() - } - - KConfigGroup config(KSharedConfig::openConfig(), QStringLiteral("Replicode")); -+ - QString executorPath = config.readEntry<QString>("replicodePath", QString()); -+ -+ // ensure we only call replicode from PATH if not given as absolute path already -+ if (!executorPath.isEmpty() && !QFileInfo(executorPath).isAbsolute()) { -+ executorPath = QStandardPaths::findExecutable(executorPath); -+ } -+ - if (executorPath.isEmpty()) { - QMessageBox::warning(m_mainWindow->window(), - i18nc("@title:window", "Replicode Executable Not Found"), -diff --git a/addons/xmlcheck/plugin_katexmlcheck.cpp b/addons/xmlcheck/plugin_katexmlcheck.cpp -index f1d52f3a7..3971550cd 100644 ---- a/addons/xmlcheck/plugin_katexmlcheck.cpp -+++ b/addons/xmlcheck/plugin_katexmlcheck.cpp -@@ -304,10 +304,18 @@ bool PluginKateXMLCheckView::slotValidate() - s << kv->document()->text(); - s.flush(); - -+ // ensure we only execute xmllint from PATH or application package - QString exe = QStandardPaths::findExecutable(QStringLiteral("xmllint")); - if (exe.isEmpty()) { - exe = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, QStringLiteral("xmllint")); - } -+ if (exe.isEmpty()) { -+ KMessageBox::error(nullptr, -+ i18n("<b>Error:</b> Failed to find xmllint. Please make " -+ "sure that xmllint is installed. It is part of libxml2.")); -+ return false; -+ } -+ - // qDebug() << "exe=" <<exe; - // // use catalogs for KDE docbook: - // if( ! getenv("XML_CATALOG_FILES") ) { -diff --git a/kate/katefileactions.cpp b/kate/katefileactions.cpp -index c56c7e1c8..09a23686c 100644 ---- a/kate/katefileactions.cpp -+++ b/kate/katefileactions.cpp -@@ -23,6 +23,7 @@ - #include <QDebug> - #include <QInputDialog> - #include <QProcess> -+#include <QStandardPaths> - #include <QUrl> - - void KateFileActions::copyFilePathToClipboard(KTextEditor::Document *doc) -@@ -137,17 +138,13 @@ void KateFileActions::deleteDocumentFile(QWidget *parent, KTextEditor::Document - } - } - --QStringList KateFileActions::supportedDiffTools() -+QVector<std::pair<QString, QString>> KateFileActions::supportedDiffTools() - { -- // LATER: check for program existence and set some boolean value accordingly -- // Can this be even done in an easy way when we don't use the absolute path to the executable? -- // See https://stackoverflow.com/questions/42444055/how-to-check-if-a-program-exists-in-path-using-qt -- -- QStringList resultList; -- resultList.push_back(QStringLiteral("kdiff3")); -- resultList.push_back(QStringLiteral("kompare")); -- resultList.push_back(QStringLiteral("meld")); -- -+ // query once if the tools are there in the path and store that -+ // we will disable the actions for the tools not found -+ static QVector<std::pair<QString, QString>> resultList{{QStringLiteral("kdiff3"), QStandardPaths::findExecutable(QStringLiteral("kdiff3"))}, -+ {QStringLiteral("kompare"), QStandardPaths::findExecutable(QStringLiteral("kompare"))}, -+ {QStringLiteral("meld"), QStandardPaths::findExecutable(QStringLiteral("meld"))}}; - return resultList; - } - -diff --git a/kate/katefileactions.h b/kate/katefileactions.h -index 524d81097..77cc5b0bf 100644 ---- a/kate/katefileactions.h -+++ b/kate/katefileactions.h -@@ -51,9 +51,9 @@ void openFilePropertiesDialog(KTextEditor::Document *document); - void deleteDocumentFile(QWidget *parent, KTextEditor::Document *document); - - /** -- * @returns a list of supported diff tools (names of the executables) -+ * @returns a list of supported diff tools (names of the executables + paths to them, empty if not found in PATH) - */ --QStringList supportedDiffTools(); -+QVector<std::pair<QString, QString>> supportedDiffTools(); - - /** - * Runs an external program to compare the underlying files of two given documents. -diff --git a/kate/katemwmodonhddialog.cpp b/kate/katemwmodonhddialog.cpp -index e0041d858..d7c79e4d4 100644 ---- a/kate/katemwmodonhddialog.cpp -+++ b/kate/katemwmodonhddialog.cpp -@@ -22,6 +22,7 @@ - #include <QHeaderView> - #include <QLabel> - #include <QPushButton> -+#include <QStandardPaths> - #include <QStyle> - #include <QTemporaryFile> - #include <QTextStream> -@@ -52,6 +53,7 @@ public: - - KateMwModOnHdDialog::KateMwModOnHdDialog(DocVector docs, QWidget *parent, const char *name) - : QDialog(parent) -+ , m_fullDiffPath(QStandardPaths::findExecutable(QStringLiteral("diff"))) - , m_proc(nullptr) - , m_diffFile(nullptr) - , m_blockAddDocument(false) -@@ -108,6 +110,7 @@ KateMwModOnHdDialog::KateMwModOnHdDialog(DocVector docs, QWidget *parent, const - "file for the selected document, and shows the difference with the " - "default application. Requires diff(1).")); - hb->addWidget(btnDiff); -+ btnDiff->setEnabled(!m_fullDiffPath.isEmpty()); - connect(btnDiff, &QPushButton::clicked, this, &KateMwModOnHdDialog::slotDiff); - - // Dialog buttons -@@ -288,9 +291,10 @@ void KateMwModOnHdDialog::slotDiff() - m_diffFile->open(); - - // Start a KProcess that creates a diff -+ // We use the full path to don't launch some random "diff" in current working directory - m_proc = new KProcess(this); - m_proc->setOutputChannelMode(KProcess::MergedChannels); -- *m_proc << QStringLiteral("diff") << QStringLiteral("-ub") << QStringLiteral("-") << doc->url().toLocalFile(); -+ *m_proc << m_fullDiffPath << QStringLiteral("-ub") << QStringLiteral("-") << doc->url().toLocalFile(); - connect(m_proc, &KProcess::readyRead, this, &KateMwModOnHdDialog::slotDataAvailable); - connect(m_proc, static_cast<void (KProcess::*)(int, QProcess::ExitStatus)>(&KProcess::finished), this, &KateMwModOnHdDialog::slotPDone); - -diff --git a/kate/katemwmodonhddialog.h b/kate/katemwmodonhddialog.h -index 11c09eab7..6fa245726 100644 ---- a/kate/katemwmodonhddialog.h -+++ b/kate/katemwmodonhddialog.h -@@ -51,6 +51,7 @@ private: - class QTreeWidget *twDocuments; - class QDialogButtonBox *dlgButtons; - class QPushButton *btnDiff; -+ QString m_fullDiffPath; - KProcess *m_proc; - QTemporaryFile *m_diffFile; - QStringList m_stateTexts; -diff --git a/kate/kateviewspace.cpp b/kate/kateviewspace.cpp -index dba2fb973..af3bb8d34 100644 ---- a/kate/kateviewspace.cpp -+++ b/kate/kateviewspace.cpp -@@ -678,8 +678,11 @@ void KateViewSpace::showContextMenu(int idx, const QPoint &globalPos) - - if (mCompareWithActive->isEnabled()) { - for (auto &&diffTool : KateFileActions::supportedDiffTools()) { -- QAction *compareAction = mCompareWithActive->addAction(diffTool); -- compareAction->setData(diffTool); -+ QAction *compareAction = mCompareWithActive->addAction(diffTool.first); -+ -+ // we use the full path to safely execute the tool, disable action if no full path => tool not found -+ compareAction->setData(diffTool.second); -+ compareAction->setEnabled(!diffTool.second.isEmpty()); - } - } - -diff --git a/shared/gitprocess.h b/shared/gitprocess.h -index 47b98b696..b0d79fac6 100644 ---- a/shared/gitprocess.h -+++ b/shared/gitprocess.h -@@ -7,6 +7,7 @@ - #pragma once - - #include <QProcess> -+#include <QStandardPaths> - - /** - * small helper function to setup a QProcess based "git" command. -@@ -17,10 +18,20 @@ - * @param process process to setup for git - * @param workingDirectory working directory to use for process - * @param arguments arguments to pass to git -+ * @return could set setup the process or did that fail, e.g. because the git executable is not available? - */ --inline void setupGitProcess(QProcess &process, const QString &workingDirectory, const QStringList &arguments) -+inline bool setupGitProcess(QProcess &process, const QString &workingDirectory, const QStringList &arguments) - { -- process.setProgram(QStringLiteral("git")); -+ // only use git from PATH -+ static const auto gitExecutable = QStandardPaths::findExecutable(QStringLiteral("git")); -+ if (gitExecutable.isEmpty()) { -+ // ensure we have no valid QProcess setup -+ process.setProgram(QString()); -+ return false; -+ } -+ -+ // setup program and arguments, ensure we do run git in the right working directory -+ process.setProgram(gitExecutable); - process.setWorkingDirectory(workingDirectory); - process.setArguments(arguments); - -@@ -37,4 +48,5 @@ inline void setupGitProcess(QProcess &process, const QString &workingDirectory, - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - env.insert(QStringLiteral("GIT_OPTIONAL_LOCKS"), QStringLiteral("0")); - process.setProcessEnvironment(env); -+ return true; - } --- -GitLab - diff --git a/source/kde/kde/patch/kate/92a9c65e30b4b63b8b116eb5c8dcb1e1a2d867bc.patch b/source/kde/kde/patch/kate/92a9c65e30b4b63b8b116eb5c8dcb1e1a2d867bc.patch deleted file mode 100644 index 6900a46c0..000000000 --- a/source/kde/kde/patch/kate/92a9c65e30b4b63b8b116eb5c8dcb1e1a2d867bc.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 92a9c65e30b4b63b8b116eb5c8dcb1e1a2d867bc Mon Sep 17 00:00:00 2001 -From: Waqar Ahmed <waqar.17a@gmail.com> -Date: Sun, 16 Jan 2022 18:39:50 +0500 -Subject: [PATCH] step down warning level when LSP not found - -Currently it gives an error which results in the widget popping up -everytime you open a file for which you don't have LSP. However, one may -have intentionally not installed the LSP for a language. - -BUG: 448549 ---- - addons/lspclient/lspclientservermanager.cpp | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/addons/lspclient/lspclientservermanager.cpp b/addons/lspclient/lspclientservermanager.cpp -index 551926e23..24e3f275b 100644 ---- a/addons/lspclient/lspclientservermanager.cpp -+++ b/addons/lspclient/lspclientservermanager.cpp -@@ -737,13 +737,13 @@ private: - server.reset(new LSPClientServer(cmdline, root, realLangId, serverConfig.value(QStringLiteral("initializationOptions")), folders)); - connect(server.data(), &LSPClientServer::stateChanged, this, &self_type::onStateChanged, Qt::UniqueConnection); - if (!server->start()) { -- QString errorMessage = i18n("Failed to start server: %1", cmdline.join(QLatin1Char(' '))); -+ QString message = i18n("Failed to start server: %1", cmdline.join(QLatin1Char(' '))); - const auto url = serverConfig.value(QStringLiteral("url")).toString(); - if (!url.isEmpty()) { -- errorMessage += QStringLiteral("\n") + i18n("Please check your PATH for the binary"); -- errorMessage += QStringLiteral("\n") + i18n("See also %1 for installation or details", url); -+ message += QStringLiteral("\n") + i18n("Please check your PATH for the binary"); -+ message += QStringLiteral("\n") + i18n("See also %1 for installation or details", url); - } -- showMessage(errorMessage, KTextEditor::Message::Error); -+ showMessage(message, KTextEditor::Message::Warning); - } else { - showMessage(i18n("Started server %2: %1", cmdline.join(QLatin1Char(' ')), serverDescription(server.data())), - KTextEditor::Message::Positive); --- -GitLab - diff --git a/source/kde/kde/patch/kate/c5d66f3b70ae4778d6162564309aee95f643e7c9.patch b/source/kde/kde/patch/kate/c5d66f3b70ae4778d6162564309aee95f643e7c9.patch deleted file mode 100644 index cc3f058d7..000000000 --- a/source/kde/kde/patch/kate/c5d66f3b70ae4778d6162564309aee95f643e7c9.patch +++ /dev/null @@ -1,124 +0,0 @@ -From c5d66f3b70ae4778d6162564309aee95f643e7c9 Mon Sep 17 00:00:00 2001 -From: Christoph Cullmann <cullmann@kde.org> -Date: Thu, 20 Jan 2022 21:00:09 +0100 -Subject: [PATCH] avoid that we execute LSP binaries from cwd - -QProcess will just use current working directory as -fallback - -that allows to execute un-wanted binaries by accident ---- - addons/lspclient/lspclientservermanager.cpp | 87 ++++++++++++--------- - 1 file changed, 51 insertions(+), 36 deletions(-) - -diff --git a/addons/lspclient/lspclientservermanager.cpp b/addons/lspclient/lspclientservermanager.cpp -index 24e3f275b..e78b4aa2d 100644 ---- a/addons/lspclient/lspclientservermanager.cpp -+++ b/addons/lspclient/lspclientservermanager.cpp -@@ -707,52 +707,67 @@ private: - } - - if (cmdline.length() > 0) { -+ // ensure we always only take the server executable from the PATH or user defined paths -+ // QProcess will take the executable even just from current working directory without this => BAD -+ auto cmd = QStandardPaths::findExecutable(cmdline[0]); -+ - // optionally search in supplied path(s) -- auto vpath = serverConfig.value(QStringLiteral("path")).toArray(); -- if (vpath.size() > 0) { -- auto cmd = QStandardPaths::findExecutable(cmdline[0]); -- if (cmd.isEmpty()) { -- // collect and expand in case home dir or other (environment) variable reference is used -- QStringList path; -- for (const auto &e : vpath) { -- auto p = e.toString(); -- editor->expandText(p, view, p); -- path.push_back(p); -- } -- cmd = QStandardPaths::findExecutable(cmdline[0], path); -- if (!cmd.isEmpty()) { -- cmdline[0] = cmd; -- } -+ const auto vpath = serverConfig.value(QStringLiteral("path")).toArray(); -+ if (cmd.isEmpty() && !vpath.isEmpty()) { -+ // collect and expand in case home dir or other (environment) variable reference is used -+ QStringList path; -+ for (const auto &e : vpath) { -+ auto p = e.toString(); -+ editor->expandText(p, view, p); -+ path.push_back(p); - } -+ cmd = QStandardPaths::findExecutable(cmdline[0], path); - } -- // an empty list is always passed here (or null) -- // the initial list is provided/updated using notification after start -- // since that is what a server is more aware of -- // and should support if it declares workspace folder capable -- // (as opposed to the new initialization property) -- LSPClientServer::FoldersType folders; -- if (useWorkspace) { -- folders = QList<LSPWorkspaceFolder>(); -- } -- server.reset(new LSPClientServer(cmdline, root, realLangId, serverConfig.value(QStringLiteral("initializationOptions")), folders)); -- connect(server.data(), &LSPClientServer::stateChanged, this, &self_type::onStateChanged, Qt::UniqueConnection); -- if (!server->start()) { -- QString message = i18n("Failed to start server: %1", cmdline.join(QLatin1Char(' '))); -+ -+ // we can only start the stuff if we did find the binary in the paths -+ if (!cmd.isEmpty()) { -+ // use full path to avoid security issues -+ cmdline[0] = cmd; -+ -+ // an empty list is always passed here (or null) -+ // the initial list is provided/updated using notification after start -+ // since that is what a server is more aware of -+ // and should support if it declares workspace folder capable -+ // (as opposed to the new initialization property) -+ LSPClientServer::FoldersType folders; -+ if (useWorkspace) { -+ folders = QList<LSPWorkspaceFolder>(); -+ } -+ server.reset(new LSPClientServer(cmdline, root, realLangId, serverConfig.value(QStringLiteral("initializationOptions")), folders)); -+ connect(server.data(), &LSPClientServer::stateChanged, this, &self_type::onStateChanged, Qt::UniqueConnection); -+ if (!server->start()) { -+ QString message = i18n("Failed to start server: %1", cmdline.join(QLatin1Char(' '))); -+ const auto url = serverConfig.value(QStringLiteral("url")).toString(); -+ if (!url.isEmpty()) { -+ message += QStringLiteral("\n") + i18n("Please check your PATH for the binary"); -+ message += QStringLiteral("\n") + i18n("See also %1 for installation or details", url); -+ } -+ showMessage(message, KTextEditor::Message::Warning); -+ } else { -+ showMessage(i18n("Started server %2: %1", cmdline.join(QLatin1Char(' ')), serverDescription(server.data())), -+ KTextEditor::Message::Positive); -+ using namespace std::placeholders; -+ server->connect(server.data(), &LSPClientServer::logMessage, this, std::bind(&self_type::onMessage, this, true, _1)); -+ server->connect(server.data(), &LSPClientServer::showMessage, this, std::bind(&self_type::onMessage, this, false, _1)); -+ server->connect(server.data(), &LSPClientServer::workDoneProgress, this, &self_type::onWorkDoneProgress); -+ server->connect(server.data(), &LSPClientServer::workspaceFolders, this, &self_type::onWorkspaceFolders, Qt::UniqueConnection); -+ } -+ } else { -+ // we didn't find the server binary at all! -+ QString message = i18n("Failed to find server binary: %1", cmdline[0]); - const auto url = serverConfig.value(QStringLiteral("url")).toString(); - if (!url.isEmpty()) { - message += QStringLiteral("\n") + i18n("Please check your PATH for the binary"); - message += QStringLiteral("\n") + i18n("See also %1 for installation or details", url); - } - showMessage(message, KTextEditor::Message::Warning); -- } else { -- showMessage(i18n("Started server %2: %1", cmdline.join(QLatin1Char(' ')), serverDescription(server.data())), -- KTextEditor::Message::Positive); -- using namespace std::placeholders; -- server->connect(server.data(), &LSPClientServer::logMessage, this, std::bind(&self_type::onMessage, this, true, _1)); -- server->connect(server.data(), &LSPClientServer::showMessage, this, std::bind(&self_type::onMessage, this, false, _1)); -- server->connect(server.data(), &LSPClientServer::workDoneProgress, this, &self_type::onWorkDoneProgress); -- server->connect(server.data(), &LSPClientServer::workspaceFolders, this, &self_type::onWorkspaceFolders, Qt::UniqueConnection); - } -+ - serverinfo.settings = serverConfig.value(QStringLiteral("settings")); - serverinfo.started = QTime::currentTime(); - serverinfo.url = serverConfig.value(QStringLiteral("url")).toString(); --- -GitLab - |