forked from qt-creator/qt-creator
ClangCodeModel: Add experimental clangd support
If the user has enabled clangd (default is off), we start up one instance per project when it is opened/changed (including build config switches), and trigger background indexing. So far, the index is used to provide results for locators and "Find Usages". Per-document functionality such as semantic highlighting and completion is still provided by libclang. Change-Id: I12532fca1b9c6278baab560e7238cba6189cde9f Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -292,7 +292,7 @@ void Client::initialize()
|
||||
QTC_ASSERT(m_state == Uninitialized, return);
|
||||
qCDebug(LOGLSPCLIENT) << "initializing language server " << m_displayName;
|
||||
InitializeParams params;
|
||||
params.setCapabilities(generateClientCapabilities());
|
||||
params.setCapabilities(m_clientCapabilities);
|
||||
params.setInitializationOptions(m_initializationOptions);
|
||||
if (m_project) {
|
||||
params.setRootUri(DocumentUri::fromFilePath(m_project->projectDirectory()));
|
||||
@@ -333,6 +333,16 @@ Client::State Client::state() const
|
||||
return m_state;
|
||||
}
|
||||
|
||||
ClientCapabilities Client::defaultClientCapabilities()
|
||||
{
|
||||
return generateClientCapabilities();
|
||||
}
|
||||
|
||||
void Client::setClientCapabilities(const LanguageServerProtocol::ClientCapabilities &caps)
|
||||
{
|
||||
m_clientCapabilities = caps;
|
||||
}
|
||||
|
||||
void Client::openDocument(TextEditor::TextDocument *document)
|
||||
{
|
||||
using namespace TextEditor;
|
||||
@@ -532,6 +542,9 @@ void Client::requestDocumentHighlights(TextEditor::TextEditorWidget *widget)
|
||||
|
||||
void Client::activateDocument(TextEditor::TextDocument *document)
|
||||
{
|
||||
if (!m_documentActionsEnabled)
|
||||
return;
|
||||
|
||||
auto uri = DocumentUri::fromFilePath(document->filePath());
|
||||
m_diagnosticManager.showDiagnostics(uri);
|
||||
SemanticHighligtingSupport::applyHighlight(document, m_highlights.value(uri), capabilities());
|
||||
@@ -558,6 +571,9 @@ void Client::activateDocument(TextEditor::TextDocument *document)
|
||||
|
||||
void Client::deactivateDocument(TextEditor::TextDocument *document)
|
||||
{
|
||||
if (!m_documentActionsEnabled)
|
||||
return;
|
||||
|
||||
m_diagnosticManager.hideDiagnostics(document);
|
||||
resetAssistProviders(document);
|
||||
document->setFormatter(nullptr);
|
||||
@@ -1241,6 +1257,9 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
|
||||
|
||||
void Client::handleDiagnostics(const PublishDiagnosticsParams ¶ms)
|
||||
{
|
||||
if (!m_documentActionsEnabled)
|
||||
return;
|
||||
|
||||
const DocumentUri &uri = params.uri();
|
||||
|
||||
const QList<Diagnostic> &diagnostics = params.diagnostics();
|
||||
@@ -1253,6 +1272,9 @@ void Client::handleDiagnostics(const PublishDiagnosticsParams ¶ms)
|
||||
|
||||
void Client::handleSemanticHighlight(const SemanticHighlightingParams ¶ms)
|
||||
{
|
||||
if (!m_documentActionsEnabled)
|
||||
return;
|
||||
|
||||
DocumentUri uri;
|
||||
LanguageClientValue<int> version;
|
||||
auto textDocument = params.textDocument();
|
||||
@@ -1283,6 +1305,9 @@ void Client::handleSemanticHighlight(const SemanticHighlightingParams ¶ms)
|
||||
|
||||
void Client::rehighlight()
|
||||
{
|
||||
if (!m_documentActionsEnabled)
|
||||
return;
|
||||
|
||||
using namespace TextEditor;
|
||||
for (auto it = m_highlights.begin(), end = m_highlights.end(); it != end; ++it) {
|
||||
if (TextDocument *doc = TextDocument::textDocumentForFilePath(it.key().toFilePath())) {
|
||||
|
||||
@@ -113,11 +113,17 @@ public:
|
||||
bool reachable() const { return m_state == Initialized; }
|
||||
|
||||
// capabilities
|
||||
static LanguageServerProtocol::ClientCapabilities defaultClientCapabilities();
|
||||
void setClientCapabilities(const LanguageServerProtocol::ClientCapabilities &caps);
|
||||
const LanguageServerProtocol::ServerCapabilities &capabilities() const;
|
||||
const DynamicCapabilities &dynamicCapabilities() const;
|
||||
void registerCapabilities(const QList<LanguageServerProtocol::Registration> ®istrations);
|
||||
void unregisterCapabilities(const QList<LanguageServerProtocol::Unregistration> &unregistrations);
|
||||
|
||||
void setLocatorsEnabled(bool enabled) { m_locatorsEnabled = enabled; }
|
||||
bool locatorsEnabled() const { return m_locatorsEnabled; }
|
||||
void setDocumentActionsEnabled(bool enabled) { m_documentActionsEnabled = enabled; }
|
||||
|
||||
// document synchronization
|
||||
void setSupportedLanguage(const LanguageFilter &filter);
|
||||
void setActivateDocumentAutomatically(bool enabled);
|
||||
@@ -226,6 +232,7 @@ private:
|
||||
QMap<TextEditor::TextEditorWidget *, QTimer *> m_documentHighlightsTimer;
|
||||
QTimer m_documentUpdateTimer;
|
||||
Utils::Id m_id;
|
||||
LanguageServerProtocol::ClientCapabilities m_clientCapabilities = defaultClientCapabilities();
|
||||
LanguageServerProtocol::ServerCapabilities m_serverCapabilities;
|
||||
DynamicCapabilities m_dynamicCapabilities;
|
||||
struct AssistProviders
|
||||
@@ -250,6 +257,8 @@ private:
|
||||
ProgressManager m_progressManager;
|
||||
bool m_activateDocAutomatically = false;
|
||||
SemanticTokenSupport m_tokentSupport;
|
||||
bool m_locatorsEnabled = true;
|
||||
bool m_documentActionsEnabled = true;
|
||||
};
|
||||
|
||||
} // namespace LanguageClient
|
||||
|
||||
@@ -57,4 +57,6 @@ QtcPlugin {
|
||||
"semantichighlightsupport.cpp",
|
||||
"semantichighlightsupport.h",
|
||||
]
|
||||
|
||||
Export { Depends { name: "LanguageServerProtocol" } }
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <texteditor/textdocument.h>
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <texteditor/textmark.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/executeondestruction.h>
|
||||
#include <utils/mimetypes/mimedatabase.h>
|
||||
#include <utils/theme/theme.h>
|
||||
@@ -375,6 +376,14 @@ Client *LanguageClientManager::clientForUri(const DocumentUri &uri)
|
||||
return clientForFilePath(uri.toFilePath());
|
||||
}
|
||||
|
||||
const QList<Client *> LanguageClientManager::clientsForProject(
|
||||
const ProjectExplorer::Project *project)
|
||||
{
|
||||
return Utils::filtered(managerInstance->m_clients, [project](const Client *c) {
|
||||
return c->project() == project;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
void LanguageClientManager::openDocumentWithClient(TextEditor::TextDocument *document, Client *client)
|
||||
{
|
||||
Client *currentClient = clientForDocument(document);
|
||||
|
||||
@@ -84,6 +84,7 @@ public:
|
||||
static Client *clientForDocument(TextEditor::TextDocument *document);
|
||||
static Client *clientForFilePath(const Utils::FilePath &filePath);
|
||||
static Client *clientForUri(const LanguageServerProtocol::DocumentUri &uri);
|
||||
static const QList<Client *> clientsForProject(const ProjectExplorer::Project *project);
|
||||
|
||||
///
|
||||
/// \brief openDocumentWithClient
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "languageclient_global.h"
|
||||
|
||||
#include <texteditor/textdocument.h>
|
||||
|
||||
#include <languageserverprotocol/languagefeatures.h>
|
||||
@@ -38,7 +40,7 @@ namespace LanguageClient {
|
||||
|
||||
class Client;
|
||||
|
||||
class SymbolSupport
|
||||
class LANGUAGECLIENT_EXPORT SymbolSupport
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(SymbolSupport)
|
||||
public:
|
||||
|
||||
@@ -214,6 +214,18 @@ WorkspaceLocatorFilter::WorkspaceLocatorFilter(const QVector<SymbolKind> &filter
|
||||
}
|
||||
|
||||
void WorkspaceLocatorFilter::prepareSearch(const QString &entry)
|
||||
{
|
||||
prepareSearch(entry, LanguageClientManager::clients(), false);
|
||||
}
|
||||
|
||||
void WorkspaceLocatorFilter::prepareSearch(const QString &entry, const QVector<Client *> &clients)
|
||||
{
|
||||
prepareSearch(entry, clients, true);
|
||||
}
|
||||
|
||||
void WorkspaceLocatorFilter::prepareSearch(const QString &entry,
|
||||
const QVector<Client *> &clients,
|
||||
bool force)
|
||||
{
|
||||
m_pendingRequests.clear();
|
||||
m_results.clear();
|
||||
@@ -222,7 +234,11 @@ void WorkspaceLocatorFilter::prepareSearch(const QString &entry)
|
||||
params.setQuery(entry);
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
for (auto client : Utils::filtered(LanguageClientManager::clients(), &Client::reachable)) {
|
||||
for (auto client : qAsConst(clients)) {
|
||||
if (!client->reachable())
|
||||
continue;
|
||||
if (!(force || client->locatorsEnabled()))
|
||||
continue;
|
||||
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> capability
|
||||
= client->capabilities().workspaceSymbolProvider();
|
||||
if (!capability.has_value())
|
||||
|
||||
@@ -74,13 +74,16 @@ private:
|
||||
Utils::optional<LanguageServerProtocol::DocumentSymbolsResult> m_currentSymbols;
|
||||
};
|
||||
|
||||
class WorkspaceLocatorFilter : public Core::ILocatorFilter
|
||||
class LANGUAGECLIENT_EXPORT WorkspaceLocatorFilter : public Core::ILocatorFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WorkspaceLocatorFilter();
|
||||
|
||||
/// request workspace symbols for all clients with enabled locator
|
||||
void prepareSearch(const QString &entry) override;
|
||||
/// force request workspace symbols for all given clients
|
||||
void prepareSearch(const QString &entry, const QVector<Client *> &clients);
|
||||
QList<Core::LocatorFilterEntry> matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future,
|
||||
const QString &entry) override;
|
||||
void accept(Core::LocatorFilterEntry selection,
|
||||
@@ -95,6 +98,7 @@ protected:
|
||||
explicit WorkspaceLocatorFilter(const QVector<LanguageServerProtocol::SymbolKind> &filter);
|
||||
|
||||
private:
|
||||
void prepareSearch(const QString &entry, const QVector<Client *> &clients, bool force);
|
||||
void handleResponse(Client *client,
|
||||
const LanguageServerProtocol::WorkspaceSymbolRequest::Response &response);
|
||||
|
||||
@@ -104,13 +108,13 @@ private:
|
||||
QVector<LanguageServerProtocol::SymbolKind> m_filterKinds;
|
||||
};
|
||||
|
||||
class WorkspaceClassLocatorFilter : public WorkspaceLocatorFilter
|
||||
class LANGUAGECLIENT_EXPORT WorkspaceClassLocatorFilter : public WorkspaceLocatorFilter
|
||||
{
|
||||
public:
|
||||
WorkspaceClassLocatorFilter();
|
||||
};
|
||||
|
||||
class WorkspaceMethodLocatorFilter : public WorkspaceLocatorFilter
|
||||
class LANGUAGECLIENT_EXPORT WorkspaceMethodLocatorFilter : public WorkspaceLocatorFilter
|
||||
{
|
||||
public:
|
||||
WorkspaceMethodLocatorFilter();
|
||||
|
||||
Reference in New Issue
Block a user