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 <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2021-08-11 12:37:52 +02:00
parent 7409168929
commit e88b4ebce8
3 changed files with 14 additions and 6 deletions

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -246,6 +246,7 @@ private:
LanguageFilter m_languagFilter;
QJsonObject m_initializationOptions;
QMap<TextEditor::TextDocument *, QString> m_openedDocument;
QSet<TextEditor::TextDocument *> m_postponedDocuments;
QMap<Utils::FilePath, int> m_documentVersions;
QMap<TextEditor::TextDocument *,
QList<LanguageServerProtocol::DidChangeTextDocumentParams::TextDocumentContentChangeEvent>>