From e88b4ebce80561400436798c43744a4a78295170 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 11 Aug 2021 12:37:52 +0200 Subject: [PATCH] clangd: open documents just once Opening a document in the language client while the server is still initializing will postpone the opening after the server is fully initialized. So if a document was scheduled for opening by ClangModelManagerSupport::onEditorOpened while clangd is still initializing, skip the superfluous opening in the ClangdClient initialize callback. Clangd seems to have issues if files are opened twice, resulting in strange diagnostics after editing the file. This is reproducible for me when starting Qt Creator with a session that contains open files. Change-Id: I200d5c8afb685403f0435e0553f5a475f75e8ea2 Reviewed-by: Christian Kandeler --- .../clangcodemodel/clangmodelmanagersupport.cpp | 3 ++- src/plugins/languageclient/client.cpp | 16 +++++++++++----- src/plugins/languageclient/client.h | 1 + 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 9a6b1ef6e15..12d70c80002 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -331,7 +331,8 @@ void ClangModelManagerSupport::updateLanguageClient(ProjectExplorer::Project *pr continue; if (fallbackClient && fallbackClient->documentOpen(editor->textDocument())) fallbackClient->closeDocument(editor->textDocument()); - client->openDocument(editor->textDocument()); + if (!client->documentOpen(editor->textDocument())) + client->openDocument(editor->textDocument()); ClangEditorDocumentProcessor::clearTextMarks(editor->textDocument()->filePath()); hasDocuments = true; } diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 4d0abf56708..a2a61f12244 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -354,10 +354,12 @@ void Client::openDocument(TextEditor::TextDocument *document) if (!isSupportedDocument(document)) return; - m_openedDocument[document] = document->plainText(); - - if (m_state != Initialized) + if (m_state != Initialized) { + m_postponedDocuments << document; return; + } + + QTC_ASSERT(!m_openedDocument.contains(document), return); const FilePath &filePath = document->filePath(); const QString method(DidOpenTextDocumentNotification::methodName); @@ -377,6 +379,8 @@ void Client::openDocument(TextEditor::TextDocument *document) return; } } + + m_openedDocument[document] = document->plainText(); connect(document, &TextDocument::contentsChangedWithPosition, this, [this, document](int position, int charsRemoved, int charsAdded) { documentContentsChanged(document, position, charsRemoved, charsAdded); @@ -427,6 +431,7 @@ void Client::closeDocument(TextEditor::TextDocument *document) deactivateDocument(document); const DocumentUri &uri = DocumentUri::fromFilePath(document->filePath()); m_highlights[uri].clear(); + m_postponedDocuments.remove(document); if (m_openedDocument.remove(document) != 0) { handleDocumentClosed(document); if (m_state == Initialized) { @@ -1452,8 +1457,9 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse) } } - for (auto it = m_openedDocument.cbegin(); it != m_openedDocument.cend(); ++it) - openDocument(it.key()); + for (TextEditor::TextDocument *doc : m_postponedDocuments) + openDocument(doc); + m_postponedDocuments.clear(); emit initialized(m_serverCapabilities); } diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index cd0c01b986d..d046064e30a 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -246,6 +246,7 @@ private: LanguageFilter m_languagFilter; QJsonObject m_initializationOptions; QMap m_openedDocument; + QSet m_postponedDocuments; QMap m_documentVersions; QMap>