Changeset View
Changeset View
Standalone View
Standalone View
addons/lspclient/lspclientservermanager.cpp
Show First 20 Lines • Show All 78 Lines • ▼ Show 20 Line(s) | |||||
79 | 79 | | |||
80 | #include <KTextEditor/Document> | 80 | #include <KTextEditor/Document> | ||
81 | #include <KTextEditor/MainWindow> | 81 | #include <KTextEditor/MainWindow> | ||
82 | #include <KTextEditor/View> | 82 | #include <KTextEditor/View> | ||
83 | #include <KTextEditor/Message> | 83 | #include <KTextEditor/Message> | ||
84 | #include <KLocalizedString> | 84 | #include <KLocalizedString> | ||
85 | #include <KTextEditor/MovingInterface> | 85 | #include <KTextEditor/MovingInterface> | ||
86 | 86 | | |||
87 | #include <QTimer> | | |||
88 | #include <QEventLoop> | | |||
89 | #include <QDir> | 87 | #include <QDir> | ||
88 | #include <QEventLoop> | ||||
89 | #include <QFileInfo> | ||||
90 | #include <QJsonArray> | 90 | #include <QJsonArray> | ||
91 | #include <QJsonObject> | 91 | #include <QJsonObject> | ||
92 | #include <QJsonDocument> | 92 | #include <QJsonDocument> | ||
93 | #include <QTimer> | ||||
94 | | ||||
95 | // helper to find a proper root dir for the given document & file name that indicate the root dir | ||||
96 | static QString rootForDocumentAndRootIndicationFileName(KTextEditor::Document *document, const QString &rootIndicationFileName) | ||||
97 | { | ||||
98 | // search only feasible if document is local file | ||||
99 | if (!document->url().isLocalFile()) { | ||||
100 | return QString(); | ||||
101 | } | ||||
102 | | ||||
103 | // search root upwards | ||||
104 | QDir dir(QFileInfo(document->url().toLocalFile()).absolutePath()); | ||||
105 | QSet<QString> seenDirectories; | ||||
106 | while (!seenDirectories.contains(dir.absolutePath())) { | ||||
107 | // update guard | ||||
108 | seenDirectories.insert(dir.absolutePath()); | ||||
109 | | ||||
110 | // some file matching our filter is there => root found! | ||||
111 | if (dir.exists(rootIndicationFileName)) { | ||||
112 | return dir.absolutePath(); | ||||
113 | } | ||||
114 | | ||||
115 | // else: cd up, if possible or abort | ||||
116 | if (!dir.cdUp()) { | ||||
117 | break; | ||||
118 | } | ||||
119 | } | ||||
120 | | ||||
121 | // no root found, bad luck | ||||
122 | return QString(); | ||||
123 | } | ||||
93 | 124 | | |||
94 | #include <memory> | 125 | #include <memory> | ||
95 | 126 | | |||
96 | // local helper; | 127 | // local helper; | ||
97 | // recursively merge top json top onto bottom json | 128 | // recursively merge top json top onto bottom json | ||
98 | static QJsonObject | 129 | static QJsonObject | ||
99 | merge(const QJsonObject & bottom, const QJsonObject & top) | 130 | merge(const QJsonObject & bottom, const QJsonObject & top) | ||
100 | { | 131 | { | ||
▲ Show 20 Lines • Show All 389 Lines • ▼ Show 20 Line(s) | 485 | { | |||
490 | if (rootv.isString()) { | 521 | if (rootv.isString()) { | ||
491 | auto sroot = rootv.toString(); | 522 | auto sroot = rootv.toString(); | ||
492 | if (QDir::isAbsolutePath(sroot)) { | 523 | if (QDir::isAbsolutePath(sroot)) { | ||
493 | rootpath = sroot; | 524 | rootpath = sroot; | ||
494 | } else if (!projectBase.isEmpty()) { | 525 | } else if (!projectBase.isEmpty()) { | ||
495 | rootpath = QDir(projectBase).absoluteFilePath(sroot); | 526 | rootpath = QDir(projectBase).absoluteFilePath(sroot); | ||
496 | } | 527 | } | ||
497 | } | 528 | } | ||
529 | | ||||
530 | /** | ||||
531 | * no explicit set root dir? search for a matching root based on some name filters | ||||
532 | * this is required for some LSP servers like rls that don't handle that on their own like clangd does | ||||
533 | */ | ||||
534 | if (rootpath.isEmpty()) { | ||||
535 | const auto fileNamesForDetection = serverConfig.value(QStringLiteral("rootIndicationFileNames")); | ||||
536 | if (fileNamesForDetection.isArray()) { | ||||
537 | // we try each file name alternative in the listed order | ||||
538 | // this allows to have preferences | ||||
539 | for (auto name : fileNamesForDetection.toArray()) { | ||||
540 | if (name.isString()) { | ||||
541 | rootpath = rootForDocumentAndRootIndicationFileName(document, name.toString()); | ||||
542 | if (!rootpath.isEmpty()) { | ||||
543 | break; | ||||
544 | } | ||||
545 | } | ||||
546 | } | ||||
547 | } | ||||
548 | } | ||||
549 | | ||||
550 | // last fallback: home directory | ||||
498 | if (rootpath.isEmpty()) { | 551 | if (rootpath.isEmpty()) { | ||
499 | rootpath = QDir::homePath(); | 552 | rootpath = QDir::homePath(); | ||
500 | } | 553 | } | ||
501 | 554 | | |||
502 | auto root = QUrl::fromLocalFile(rootpath); | 555 | auto root = QUrl::fromLocalFile(rootpath); | ||
503 | auto server = m_servers.value(root).value(mode); | 556 | auto server = m_servers.value(root).value(mode); | ||
504 | if (!server) { | 557 | if (!server) { | ||
505 | QStringList cmdline; | 558 | QStringList cmdline; | ||
Show All 32 Lines | 583 | { | |||
538 | static auto defaultConfig = QJsonObject { | 591 | static auto defaultConfig = QJsonObject { | ||
539 | { QStringLiteral("servers"), | 592 | { QStringLiteral("servers"), | ||
540 | QJsonObject { | 593 | QJsonObject { | ||
541 | { QStringLiteral("Python"), | 594 | { QStringLiteral("Python"), | ||
542 | makeServerConfig(QStringLiteral("python3 -m pyls --check-parent-process")) }, | 595 | makeServerConfig(QStringLiteral("python3 -m pyls --check-parent-process")) }, | ||
543 | { QStringLiteral("C"), | 596 | { QStringLiteral("C"), | ||
544 | makeServerConfig(QStringLiteral("clangd -log=%1 --background-index").arg(m_plugin->m_debugMode ? QStringLiteral("verbose") : QStringLiteral("error"))) }, | 597 | makeServerConfig(QStringLiteral("clangd -log=%1 --background-index").arg(m_plugin->m_debugMode ? QStringLiteral("verbose") : QStringLiteral("error"))) }, | ||
545 | { QStringLiteral("C++"), | 598 | { QStringLiteral("C++"), | ||
546 | QJsonObject { { QStringLiteral("use"), QStringLiteral("C") } } } | 599 | QJsonObject { { QStringLiteral("use"), QStringLiteral("C") } } }, | ||
600 | { QStringLiteral("Rust"), QJsonObject { | ||||
601 | { QStringLiteral("command"), QStringLiteral("rls") }, | ||||
602 | { QStringLiteral("rootIndicationFileNames"), QJsonArray { QStringLiteral("Cargo.lock"), QStringLiteral("Cargo.toml") } } | ||||
603 | } | ||||
604 | } | ||||
547 | } | 605 | } | ||
548 | } | 606 | } | ||
549 | }; | 607 | }; | ||
550 | 608 | | |||
551 | m_serverConfig = defaultConfig; | 609 | m_serverConfig = defaultConfig; | ||
552 | 610 | | |||
553 | // consider specified configuration | 611 | // consider specified configuration | ||
554 | const auto& configPath = m_plugin->m_configPath.path(); | 612 | const auto& configPath = m_plugin->m_configPath.path(); | ||
▲ Show 20 Lines • Show All 125 Lines • Show Last 20 Lines |