Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions annotations.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
margin: 0;
border-width: 0;
}
.lsp_annotation .errors {
.lsp_annotation .error {
color: color(var(--redish) alpha(0.85));
}
.lsp_annotation .warnings {
.lsp_annotation .warning {
color: color(var(--yellowish) alpha(0.85));
}
.lsp_annotation .info {
.lsp_annotation .information {
color: color(var(--bluish) alpha(0.85));
}
.lsp_annotation .hints {
.lsp_annotation .hint {
color: color(var(--bluish) alpha(0.85));
}
1 change: 1 addition & 0 deletions plugin/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class RegionKey(StrEnum):
SHOW_DEFINITIONS_KEY = 'show_definitions'

# Region flags
DIAGNOSTIC_ICON_FLAGS = sublime.RegionFlags.HIDE_ON_MINIMAP | sublime.RegionFlags.DRAW_NO_FILL | sublime.RegionFlags.DRAW_NO_OUTLINE | sublime.RegionFlags.NO_UNDO # noqa: E501
DOCUMENT_LINK_FLAGS = sublime.RegionFlags.HIDE_ON_MINIMAP | sublime.RegionFlags.DRAW_NO_FILL | sublime.RegionFlags.DRAW_NO_OUTLINE | sublime.RegionFlags.DRAW_SOLID_UNDERLINE | sublime.RegionFlags.NO_UNDO # noqa: E501
REGIONS_INITIALIZE_FLAGS = sublime.RegionFlags.HIDDEN | sublime.RegionFlags.NO_UNDO
SEMANTIC_TOKEN_FLAGS = sublime.RegionFlags.DRAW_NO_OUTLINE | sublime.RegionFlags.NO_UNDO
Expand Down
2 changes: 1 addition & 1 deletion plugin/core/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ def diagnostics_highlight_style_flags(self) -> list[sublime.RegionFlags | None]:
flags.append(self._style_str_to_flag(user_style))
return flags
else:
# Defaults are defined in DIAGNOSTIC_SEVERITY in plugin/core/views.py
# Defaults are defined in DIAGNOSTIC_STYLES in plugin/core/views.py
return [None] * 4 # default styling


Expand Down
82 changes: 58 additions & 24 deletions plugin/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
from .types import ClientConfig
from .url import parse_uri
from .workspace import is_subpath_of
from dataclasses import dataclass
from typing import Any
from typing import Callable
from typing import cast
Expand All @@ -76,34 +77,66 @@
_baseflags = sublime.RegionFlags.DRAW_NO_FILL | sublime.RegionFlags.DRAW_NO_OUTLINE | sublime.RegionFlags.DRAW_EMPTY_AS_OVERWRITE | sublime.RegionFlags.NO_UNDO # noqa: E501
_multilineflags = sublime.RegionFlags.DRAW_NO_FILL | sublime.RegionFlags.NO_UNDO

DIAGNOSTIC_SEVERITY: list[tuple[str, str, str, str, sublime.RegionFlags, sublime.RegionFlags]] = [
# Kind CSS class Scope for color Icon resource add_regions flags for single-line diagnostic multi-line diagnostic # noqa: E501
("error", "errors", "region.redish markup.error.lsp", "Packages/LSP/icons/error.png", _baseflags | sublime.RegionFlags.DRAW_SQUIGGLY_UNDERLINE, _multilineflags), # noqa: E501
("warning", "warnings", "region.yellowish markup.warning.lsp", "Packages/LSP/icons/warning.png", _baseflags | sublime.RegionFlags.DRAW_SQUIGGLY_UNDERLINE, _multilineflags), # noqa: E501
("info", "info", "region.bluish markup.info.lsp", "Packages/LSP/icons/info.png", _baseflags | sublime.RegionFlags.DRAW_STIPPLED_UNDERLINE, _multilineflags), # noqa: E501
("hint", "hints", "region.bluish markup.info.hint.lsp", "", _baseflags | sublime.RegionFlags.DRAW_STIPPLED_UNDERLINE, _multilineflags), # noqa: E501
]

@dataclass
class DiagnosticStyle:
kind: str
css_class: str
region_scope: str
icon_resource: str
single_line_region_flags: sublime.RegionFlags
multi_line_region_flags: sublime.RegionFlags


DIAGNOSTIC_STYLES: dict[DiagnosticSeverity, DiagnosticStyle] = {
DiagnosticSeverity.Error: DiagnosticStyle(
'error',
'error',
'region.redish markup.error.lsp',
'Packages/LSP/icons/error.png',
_baseflags | sublime.RegionFlags.DRAW_SQUIGGLY_UNDERLINE,
_multilineflags
),
DiagnosticSeverity.Warning: DiagnosticStyle(
'warning',
'warning',
'region.yellowish markup.warning.lsp',
'Packages/LSP/icons/warning.png',
_baseflags | sublime.RegionFlags.DRAW_SQUIGGLY_UNDERLINE,
_multilineflags
),
DiagnosticSeverity.Information: DiagnosticStyle(
'info',
'information',
'region.bluish markup.info.lsp',
'Packages/LSP/icons/info.png',
_baseflags | sublime.RegionFlags.DRAW_STIPPLED_UNDERLINE,
_multilineflags
),
DiagnosticSeverity.Hint: DiagnosticStyle(
'hint',
'hint',
'region.bluish markup.info.hint.lsp',
'',
_baseflags | sublime.RegionFlags.DRAW_STIPPLED_UNDERLINE,
_multilineflags
),
}


class DiagnosticSeverityData:

__slots__ = ('regions', 'regions_with_tag', 'annotations', 'scope', 'icon')
__slots__ = ('regions', 'regions_with_tag', 'annotations')

def __init__(self, severity: int) -> None:
def __init__(self) -> None:
self.regions: list[sublime.Region] = []
self.regions_with_tag: dict[DiagnosticTag, list[sublime.Region]] = {}
self.annotations: list[str] = []
_, _, self.scope, self.icon, _, _ = DIAGNOSTIC_SEVERITY[severity - 1]
if userprefs().diagnostics_gutter_marker != "sign":
self.icon = "" if severity == DiagnosticSeverity.Hint else userprefs().diagnostics_gutter_marker


class InvalidUriSchemeException(Exception):
def __init__(self, uri: str) -> None:
self.uri = uri

def __str__(self) -> str:
return f"invalid URI scheme: {self.uri}"
super().__init__(f"invalid URI scheme: {uri}")
Comment on lines 137 to +139
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by change. Was unnecessarily complicated.



def get_line(window: sublime.Window, file_name: str, row: int, strip: bool = True) -> str:
Expand Down Expand Up @@ -698,16 +731,17 @@ def document_color_params(view: sublime.View) -> DocumentColorParams:
return {"textDocument": text_document_identifier(view)}


def format_severity(severity: int) -> str:
if 1 <= severity <= len(DIAGNOSTIC_SEVERITY):
return DIAGNOSTIC_SEVERITY[severity - 1][0]
return "???"


def diagnostic_severity(diagnostic: Diagnostic) -> DiagnosticSeverity:
return diagnostic.get("severity", DiagnosticSeverity.Error)


def diagnostic_icon(severity: DiagnosticSeverity) -> str:
if userprefs().diagnostics_gutter_marker == "sign":
return DIAGNOSTIC_STYLES[severity].icon_resource
else:
return "" if severity == DiagnosticSeverity.Hint else userprefs().diagnostics_gutter_marker


def format_diagnostics_for_annotation(diagnostics: list[Diagnostic], css_class: str) -> list[str]:
annotations = []
for diagnostic in diagnostics:
Expand Down Expand Up @@ -735,7 +769,7 @@ def format_diagnostic_for_panel(diagnostic: Diagnostic) -> tuple[str, int | None
result = " {:>4}:{:<4}{:<8}{}".format(
diagnostic["range"]["start"]["line"] + 1,
diagnostic["range"]["start"]["character"] + 1,
format_severity(diagnostic_severity(diagnostic)),
DIAGNOSTIC_STYLES[diagnostic_severity(diagnostic)].kind,
lines[0]
)
if formatted != "" or code is not None:
Expand Down Expand Up @@ -851,7 +885,7 @@ def format_diagnostic_for_html(config: ClientConfig, diagnostic: Diagnostic, bas
if related_infos := diagnostic.get("relatedInformation"):
info = "<br>".join(_format_diagnostic_related_info(config, info, base_dir) for info in related_infos)
html += '<br>' + _html_element("pre", info, class_name="related_info", escape=False)
severity_class = DIAGNOSTIC_SEVERITY[diagnostic_severity(diagnostic) - 1][1]
severity_class = DIAGNOSTIC_STYLES[diagnostic_severity(diagnostic)].css_class
return _html_element("pre", html, class_name=severity_class, escape=False)


Expand Down
4 changes: 2 additions & 2 deletions plugin/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
from .core.settings import userprefs
from .core.types import DocumentSelector_
from .core.url import normalize_uri
from .core.views import DIAGNOSTIC_SEVERITY
from .core.views import diagnostic_severity
from .core.views import DIAGNOSTIC_STYLES
from .core.views import format_diagnostics_for_annotation
from typing import Union
import itertools
Expand Down Expand Up @@ -141,7 +141,7 @@ def draw(self, diagnostics: list[tuple[Diagnostic, sublime.Region]]) -> None:
continue
matching_diagnostics[0].append(diagnostic)
matching_diagnostics[1].append(region)
css_class = DIAGNOSTIC_SEVERITY[severity - 1][1]
css_class = DIAGNOSTIC_STYLES[severity].css_class
annotations = format_diagnostics_for_annotation(matching_diagnostics[0], css_class)
color = self._severity_colors[severity]
self._view.add_regions(
Expand Down
7 changes: 4 additions & 3 deletions plugin/session_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from ..protocol import CodeLens
from ..protocol import ColorInformation
from ..protocol import Diagnostic
from ..protocol import DiagnosticSeverity
from ..protocol import DiagnosticTag
from ..protocol import DocumentDiagnosticParams
from ..protocol import DocumentDiagnosticReport
Expand Down Expand Up @@ -158,7 +159,7 @@ def __init__(self, session_view: SessionViewProtocol, buffer_id: int, uri: Docum
self._pending_changes: PendingChanges | None = None
self.pending_refreshes: RequestFlags = RequestFlags.NONE
self._diagnostics: list[tuple[Diagnostic, sublime.Region]] = []
self.diagnostics_data_per_severity: dict[tuple[int, bool], DiagnosticSeverityData] = {}
self.diagnostics_data_per_severity: dict[tuple[DiagnosticSeverity, bool], DiagnosticSeverityData] = {}
self._diagnostics_versions: dict[DiagnosticsIdentifier, int] = {}
self.diagnostics_flags = 0
self._diagnostics_are_visible = False
Expand Down Expand Up @@ -694,14 +695,14 @@ def on_diagnostics_async(
return
diagnostics_version = version
diagnostics: list[tuple[Diagnostic, sublime.Region]] = []
data_per_severity: dict[tuple[int, bool], DiagnosticSeverityData] = {}
data_per_severity: dict[tuple[DiagnosticSeverity, bool], DiagnosticSeverityData] = {}
for diagnostic in raw_diagnostics:
region = range_to_region(diagnostic["range"], view)
severity = diagnostic_severity(diagnostic)
key = (severity, len(view.split_by_newlines(region)) > 1)
data = data_per_severity.get(key)
if data is None:
data = DiagnosticSeverityData(severity)
data = DiagnosticSeverityData()
data_per_severity[key] = data
if tags := diagnostic.get('tags', []):
for tag in tags:
Expand Down
24 changes: 14 additions & 10 deletions plugin/session_view.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from __future__ import annotations

from ..protocol import Command
from ..protocol import DiagnosticSeverity
from ..protocol import DocumentHighlightKind
from ..protocol import DocumentUri
from .core.active_request import ActiveRequest
from .core.constants import DIAGNOSTIC_ICON_FLAGS
from .core.constants import DIAGNOSTIC_TAG_SCOPES
from .core.constants import HOVER_ENABLED_KEY
from .core.constants import RegionKey
Expand All @@ -16,7 +18,8 @@
from .core.sessions import Session
from .core.settings import userprefs
from .core.views import ChangeEventAction
from .core.views import DIAGNOSTIC_SEVERITY
from .core.views import diagnostic_icon
from .core.views import DIAGNOSTIC_STYLES
from .core.views import document_highlight_key
from .core.views import make_command_link
from .core.views import range_to_region
Expand Down Expand Up @@ -94,7 +97,7 @@ def on_before_remove(self) -> None:
self.session.cancel_request_async(request_id)
self.session.unregister_session_view_async(self)
self.session.config.erase_view_status(self.view)
for severity in reversed(range(1, len(DIAGNOSTIC_SEVERITY) + 1)):
for severity in reversed(DIAGNOSTIC_STYLES.keys()):
self.view.erase_regions(f"{self.diagnostics_key(severity, False)}_icon")
self.view.erase_regions(f"{self.diagnostics_key(severity, False)}_underline")
self.view.erase_regions(f"{self.diagnostics_key(severity, True)}_icon")
Expand Down Expand Up @@ -294,7 +297,7 @@ def shutdown_async(self) -> None:
if listener := self.listener():
listener.on_session_shutdown_async(self.session)

def diagnostics_key(self, severity: int, multiline: bool) -> str:
def diagnostics_key(self, severity: DiagnosticSeverity, multiline: bool) -> str:
return "lsp{}d{}{}".format(self.session.config.name, "m" if multiline else "s", severity)

def present_diagnostics_async(self, is_view_visible: bool) -> None:
Expand All @@ -306,19 +309,18 @@ def _redraw_diagnostics_async(self) -> None:
flags = userprefs().diagnostics_highlight_style_flags() # for single lines
multiline_flags = None if userprefs().show_multiline_diagnostics_highlights else sublime.RegionFlags.DRAW_NO_FILL | sublime.RegionFlags.DRAW_NO_OUTLINE | sublime.RegionFlags.NO_UNDO # noqa: E501
level = userprefs().show_diagnostics_severity_level
for sev in reversed(range(1, len(DIAGNOSTIC_SEVERITY) + 1)):
self._draw_diagnostics(sev, level, flags[sev - 1] or DIAGNOSTIC_SEVERITY[sev - 1][4], multiline=False)
self._draw_diagnostics(sev, level, multiline_flags or DIAGNOSTIC_SEVERITY[sev - 1][5], multiline=True)
for sev, style in reversed(DIAGNOSTIC_STYLES.items()):
self._draw_diagnostics(sev, level, flags[sev - 1] or style.single_line_region_flags, multiline=False)
self._draw_diagnostics(sev, level, multiline_flags or style.multi_line_region_flags, multiline=True)
self._diagnostic_annotations.draw(self.session_buffer.diagnostics)

def _draw_diagnostics(
self,
severity: int,
severity: DiagnosticSeverity,
max_severity_level: int,
flags: sublime.RegionFlags,
multiline: bool
) -> None:
ICON_FLAGS = sublime.RegionFlags.HIDE_ON_MINIMAP | sublime.RegionFlags.DRAW_NO_FILL | sublime.RegionFlags.DRAW_NO_OUTLINE | sublime.RegionFlags.NO_UNDO # noqa: E501
key = self.diagnostics_key(severity, multiline)
tags = {tag: TagData(f'{key}_tags_{tag}') for tag in DIAGNOSTIC_TAG_SCOPES}
data = self._session_buffer.diagnostics_data_per_severity.get((severity, multiline))
Expand All @@ -332,8 +334,10 @@ def _draw_diagnostics(
tags[tag].scope = tag_scope
else:
non_tag_regions.extend(regions)
self.view.add_regions(f"{key}_icon", non_tag_regions, data.scope, data.icon, ICON_FLAGS)
self.view.add_regions(f"{key}_underline", non_tag_regions, data.scope, "", flags)
region_scope = DIAGNOSTIC_STYLES[severity].region_scope
icon = diagnostic_icon(severity)
self.view.add_regions(f"{key}_icon", non_tag_regions, region_scope, icon, DIAGNOSTIC_ICON_FLAGS)
self.view.add_regions(f"{key}_underline", non_tag_regions, region_scope, "", flags)
else:
self.view.erase_regions(f"{key}_icon")
self.view.erase_regions(f"{key}_underline")
Expand Down
25 changes: 10 additions & 15 deletions popups.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,25 @@
margin-bottom: 0.5rem;
font-family: var(--mdpopups-font-mono);
}
.errors {
.error,
.warning,
.information,
.hint {
border-width: 0;
background-color: color(var(--redish) alpha(0.25));
color: var(--foreground);
padding: 0.5rem;
white-space: pre-wrap;
}
.warnings {
border-width: 0;
.error {
background-color: color(var(--redish) alpha(0.25));
}
.warning {
background-color: color(var(--yellowish) alpha(0.25));
color: var(--foreground);
padding: 0.5rem;
}
.info {
border-width: 0;
.information {
background-color: color(var(--bluish) alpha(0.25));
color: var(--foreground);
padding: 0.5rem;
}
.hints {
border-width: 0;
.hint {
background-color: color(var(--bluish) alpha(0.25));
color: var(--foreground);
padding: 0.5rem;
}
.actions, .code-actions {
font-family: system;
Expand Down