LanguageClient: allow generating specialized extra selections

for LanguageClient Diagnostics

Change-Id: Ib7226aaaa420d4c7531b9c534ab193d1b22b467d
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2022-04-12 14:37:29 +02:00
parent 61c6f532b2
commit 71b84417b3
2 changed files with 37 additions and 25 deletions

View File

@@ -40,7 +40,6 @@
#include <QAction> #include <QAction>
#include <QApplication> #include <QApplication>
#include <QClipboard> #include <QClipboard>
#include <QTextEdit>
using namespace LanguageServerProtocol; using namespace LanguageServerProtocol;
using namespace Utils; using namespace Utils;
@@ -68,6 +67,7 @@ public:
DiagnosticManager::DiagnosticManager(Client *client) DiagnosticManager::DiagnosticManager(Client *client)
: m_client(client) : m_client(client)
, m_extraSelectionsId(TextEditorWidget::CodeWarningsSelection)
{ {
} }
@@ -88,7 +88,7 @@ void DiagnosticManager::hideDiagnostics(const Utils::FilePath &filePath)
{ {
if (auto doc = TextDocument::textDocumentForFilePath(filePath)) { if (auto doc = TextDocument::textDocumentForFilePath(filePath)) {
for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc)) for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc))
editor->editorWidget()->setExtraSelections(TextEditorWidget::CodeWarningsSelection, {}); editor->editorWidget()->setExtraSelections(m_extraSelectionsId, {});
} }
qDeleteAll(m_marks.take(filePath)); qDeleteAll(m_marks.take(filePath));
} }
@@ -98,21 +98,6 @@ QList<Diagnostic> DiagnosticManager::filteredDiagnostics(const QList<Diagnostic>
return diagnostics; return diagnostics;
} }
static QTextEdit::ExtraSelection toDiagnosticsSelections(const Diagnostic &diagnostic,
QTextDocument *textDocument)
{
QTextCursor cursor(textDocument);
cursor.setPosition(diagnostic.range().start().toPositionInDocument(textDocument));
cursor.setPosition(diagnostic.range().end().toPositionInDocument(textDocument),
QTextCursor::KeepAnchor);
const FontSettings &fontSettings = TextEditorSettings::fontSettings();
const DiagnosticSeverity severity = diagnostic.severity().value_or(DiagnosticSeverity::Warning);
const TextStyle style = severity == DiagnosticSeverity::Error ? C_ERROR : C_WARNING;
return QTextEdit::ExtraSelection{cursor, fontSettings.toTextCharFormat(style)};
}
void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version) void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version)
{ {
const FilePath &filePath = uri.toFilePath(); const FilePath &filePath = uri.toFilePath();
@@ -125,17 +110,15 @@ void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version)
const bool isProjectFile = m_client->project() const bool isProjectFile = m_client->project()
&& m_client->project()->isKnownFile(filePath); && m_client->project()->isKnownFile(filePath);
for (const Diagnostic &diagnostic : versionedDiagnostics.diagnostics) { for (const Diagnostic &diagnostic : versionedDiagnostics.diagnostics) {
extraSelections << toDiagnosticsSelections(diagnostic, doc->document()); extraSelections << createDiagnosticSelection(diagnostic, doc->document());
marks.append(createTextMark(filePath, diagnostic, isProjectFile)); marks.append(createTextMark(filePath, diagnostic, isProjectFile));
} }
if (!marks.isEmpty()) if (!marks.isEmpty())
emit textMarkCreated(filePath); emit textMarkCreated(filePath);
} }
for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc)) { for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc))
editor->editorWidget()->setExtraSelections(TextEditorWidget::CodeWarningsSelection, editor->editorWidget()->setExtraSelections(m_extraSelectionsId, extraSelections);
extraSelections);
}
} }
} }
@@ -156,6 +139,28 @@ TextEditor::TextMark *DiagnosticManager::createTextMark(const FilePath &filePath
return mark; return mark;
} }
QTextEdit::ExtraSelection DiagnosticManager::createDiagnosticSelection(
const LanguageServerProtocol::Diagnostic &diagnostic, QTextDocument *textDocument) const
{
QTextCursor cursor(textDocument);
cursor.setPosition(diagnostic.range().start().toPositionInDocument(textDocument));
cursor.setPosition(diagnostic.range().end().toPositionInDocument(textDocument),
QTextCursor::KeepAnchor);
const FontSettings &fontSettings = TextEditorSettings::fontSettings();
const DiagnosticSeverity severity = diagnostic.severity().value_or(DiagnosticSeverity::Warning);
const TextStyle style = severity == DiagnosticSeverity::Error ? C_ERROR : C_WARNING;
return QTextEdit::ExtraSelection{cursor, fontSettings.toTextCharFormat(style)};
}
void DiagnosticManager::setExtraSelectionsId(const Utils::Id &extraSelectionsId)
{
// this function should be called before any diagnostics are handled
QTC_CHECK(m_diagnostics.isEmpty());
m_extraSelectionsId = extraSelectionsId;
}
void DiagnosticManager::clearDiagnostics() void DiagnosticManager::clearDiagnostics()
{ {
for (const DocumentUri &uri : m_diagnostics.keys()) for (const DocumentUri &uri : m_diagnostics.keys())

View File

@@ -32,6 +32,7 @@
#include <utils/id.h> #include <utils/id.h>
#include <QMap> #include <QMap>
#include <QTextEdit>
#include <functional> #include <functional>
@@ -49,7 +50,7 @@ class LANGUAGECLIENT_EXPORT DiagnosticManager : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit DiagnosticManager(Client *client); explicit DiagnosticManager(Client *client);
~DiagnosticManager(); ~DiagnosticManager() override;
virtual void setDiagnostics(const LanguageServerProtocol::DocumentUri &uri, virtual void setDiagnostics(const LanguageServerProtocol::DocumentUri &uri,
const QList<LanguageServerProtocol::Diagnostic> &diagnostics, const QList<LanguageServerProtocol::Diagnostic> &diagnostics,
@@ -77,15 +78,21 @@ protected:
virtual TextEditor::TextMark *createTextMark(const Utils::FilePath &filePath, virtual TextEditor::TextMark *createTextMark(const Utils::FilePath &filePath,
const LanguageServerProtocol::Diagnostic &diagnostic, const LanguageServerProtocol::Diagnostic &diagnostic,
bool isProjectFile) const; bool isProjectFile) const;
virtual QTextEdit::ExtraSelection createDiagnosticSelection(
const LanguageServerProtocol::Diagnostic &diagnostic, QTextDocument *textDocument) const;
void setExtraSelectionsId(const Utils::Id &extraSelectionsId);
private: private:
struct VersionedDiagnostics { struct VersionedDiagnostics
{
Utils::optional<int> version; Utils::optional<int> version;
QList<LanguageServerProtocol::Diagnostic> diagnostics; QList<LanguageServerProtocol::Diagnostic> diagnostics;
}; };
QMap<LanguageServerProtocol::DocumentUri, VersionedDiagnostics> m_diagnostics; QMap<LanguageServerProtocol::DocumentUri, VersionedDiagnostics> m_diagnostics;
QMap<Utils::FilePath, QList<TextEditor::TextMark *>> m_marks; QMap<Utils::FilePath, QList<TextEditor::TextMark *>> m_marks;
Client *m_client; Client *m_client;
Utils::Id m_extraSelectionsId;
}; };
} // namespace LanguageClient } // namespace LanguageClient