LanguageClient: disable diagnostics after document changes

Calculating new diagnostics after a document change can take a while.
The old ClangCodeModel disabled diagnostics (changed the color to gray)
that were reported before the last document change after some time.
Adapt this behavior to Clangd and other LSP based codemodels.

Change-Id: I0589ba0d0c023f6e7ea3e97fc5b45eb156ddcd37
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2022-05-23 12:33:01 +02:00
parent 16aaf8c59c
commit 4ab935349f
3 changed files with 31 additions and 10 deletions

View File

@@ -918,6 +918,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
{
if (!d->m_openedDocument.contains(document) || !reachable())
return;
d->m_diagnosticManager->disableDiagnostics(document);
const QString method(DidChangeTextDocumentNotification::methodName);
TextDocumentSyncKind syncKind = d->m_serverCapabilities.textDocumentSyncKindHelper();
if (Utils::optional<bool> registered = d->m_dynamicCapabilities.isRegistered(method)) {

View File

@@ -90,7 +90,7 @@ void DiagnosticManager::hideDiagnostics(const Utils::FilePath &filePath)
for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc))
editor->editorWidget()->setExtraSelections(m_extraSelectionsId, {});
}
qDeleteAll(m_marks.take(filePath));
m_marks.remove(filePath);
}
QList<Diagnostic> DiagnosticManager::filteredDiagnostics(const QList<Diagnostic> &diagnostics) const
@@ -98,6 +98,17 @@ QList<Diagnostic> DiagnosticManager::filteredDiagnostics(const QList<Diagnostic>
return diagnostics;
}
void DiagnosticManager::disableDiagnostics(TextEditor::TextDocument *document)
{
Marks &marks = m_marks[document->filePath()];
if (!marks.enabled)
return;
for (TextEditor::TextMark *mark : marks.marks)
mark->setColor(Utils::Theme::Color::IconsDisabledColor);
marks.enabled = false;
}
void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version)
{
const FilePath &filePath = uri.toFilePath();
@@ -106,7 +117,7 @@ void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version)
const VersionedDiagnostics &versionedDiagnostics = m_diagnostics.value(uri);
if (versionedDiagnostics.version.value_or(version) == version
&& !versionedDiagnostics.diagnostics.isEmpty()) {
QList<TextEditor::TextMark *> &marks = m_marks[filePath];
Marks &marks = m_marks[filePath];
const bool isProjectFile = m_client->project()
&& m_client->project()->isKnownFile(filePath);
for (const Diagnostic &diagnostic : versionedDiagnostics.diagnostics) {
@@ -115,9 +126,9 @@ void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version)
if (!selection.cursor.isNull())
extraSelections << selection;
if (TextEditor::TextMark *mark = createTextMark(filePath, diagnostic, isProjectFile))
marks.append(mark);
marks.marks.append(mark);
}
if (!marks.isEmpty())
if (!marks.marks.isEmpty())
emit textMarkCreated(filePath);
}
@@ -170,11 +181,7 @@ void DiagnosticManager::clearDiagnostics()
for (const DocumentUri &uri : m_diagnostics.keys())
hideDiagnostics(uri.toFilePath());
m_diagnostics.clear();
if (!QTC_GUARD(m_marks.isEmpty())) {
for (const QList<TextEditor::TextMark *> &marks : qAsConst(m_marks))
qDeleteAll(marks);
m_marks.clear();
}
QTC_ASSERT(m_marks.isEmpty(), m_marks.clear());
}
QList<Diagnostic> DiagnosticManager::diagnosticsAt(const DocumentUri &uri,
@@ -218,4 +225,9 @@ bool DiagnosticManager::hasDiagnostics(const TextDocument *doc) const
return !it->diagnostics.isEmpty();
}
DiagnosticManager::Marks::~Marks()
{
qDeleteAll(marks);
}
} // namespace LanguageClient

View File

@@ -61,6 +61,7 @@ public:
virtual QList<LanguageServerProtocol::Diagnostic> filteredDiagnostics(
const QList<LanguageServerProtocol::Diagnostic> &diagnostics) const;
void disableDiagnostics(TextEditor::TextDocument *document);
void clearDiagnostics();
QList<LanguageServerProtocol::Diagnostic> diagnosticsAt(
@@ -91,7 +92,14 @@ private:
QList<LanguageServerProtocol::Diagnostic> diagnostics;
};
QMap<LanguageServerProtocol::DocumentUri, VersionedDiagnostics> m_diagnostics;
QMap<Utils::FilePath, QList<TextEditor::TextMark *>> m_marks;
class Marks
{
public:
~Marks();
bool enabled = true;
QList<TextEditor::TextMark *> marks;
};
QMap<Utils::FilePath, Marks> m_marks;
Client *m_client;
Utils::Id m_extraSelectionsId;
};