Skip to content

Commit

Permalink
Merge branch 'main' into feat/diag-annotations
Browse files Browse the repository at this point in the history
* main:
  Don't trigger code action requests for background views (#2108)
  Ignore diagnostics for files in folder_exclude_patterns (#2113)
  Remove unnecessary is_range_equal function (#2114)
  • Loading branch information
rchl committed Nov 9, 2022
2 parents 083f692 + 0267a1a commit 9b9fc0b
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 54 deletions.
27 changes: 15 additions & 12 deletions plugin/core/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
from .types import method_to_capability
from .types import SettingsRegistration
from .types import sublime_pattern_to_glob
from .typing import Callable, cast, Dict, Any, Optional, List, Tuple, Generator, Iterable, Type, Protocol, Mapping, TypeVar, Union # noqa: E501
from .typing import Callable, cast, Dict, Any, Optional, List, Tuple, Generator, Iterable, Type, Protocol, Mapping, Set, TypeVar, Union # noqa: E501
from .url import filename_to_uri
from .url import parse_uri
from .version import __version__
Expand Down Expand Up @@ -494,7 +494,7 @@ def has_capability_async(self, capability_path: str) -> bool:
def shutdown_async(self) -> None:
...

def present_diagnostics_async(self) -> None:
def present_diagnostics_async(self, is_view_visible: bool) -> None:
...

def on_request_started_async(self, request_id: int, request: Request) -> None:
Expand Down Expand Up @@ -552,7 +552,9 @@ def unregister_capability_async(
) -> None:
...

def on_diagnostics_async(self, raw_diagnostics: List[Diagnostic], version: Optional[int]) -> None:
def on_diagnostics_async(
self, raw_diagnostics: List[Diagnostic], version: Optional[int], visible_session_views: Set[SessionViewProtocol]
) -> None:
...

def get_document_link_at_point(self, view: sublime.View, point: int) -> Optional[DocumentLink]:
Expand Down Expand Up @@ -633,7 +635,7 @@ def diagnostics_intersecting_async(
return self.diagnostics_intersecting_region_async(region_or_point)

@abstractmethod
def on_diagnostics_updated_async(self) -> None:
def on_diagnostics_updated_async(self, is_view_visible: bool) -> None:
raise NotImplementedError()

@abstractmethod
Expand Down Expand Up @@ -1598,12 +1600,12 @@ def decode_semantic_token(
return decode_semantic_token(
types_legend, modifiers_legend, self._semantic_tokens_map, token_type_encoded, token_modifiers_encoded)

def session_views_by_visibility(self) -> Tuple[List[SessionViewProtocol], List[SessionViewProtocol]]:
visible_session_views = [] # type: List[SessionViewProtocol]
not_visible_session_views = [] # type: List[SessionViewProtocol]
selected_sheets = []
def session_views_by_visibility(self) -> Tuple[Set[SessionViewProtocol], Set[SessionViewProtocol]]:
visible_session_views = set() # type: Set[SessionViewProtocol]
not_visible_session_views = set() # type: Set[SessionViewProtocol]
selected_sheets = set() # type: Set[sublime.Sheet]
for group in range(self.window.num_groups()):
selected_sheets.extend(self.window.selected_sheets_in_group(group))
selected_sheets = selected_sheets.union(self.window.selected_sheets_in_group(group))
for sheet in self.window.sheets():
view = sheet.view()
if not view:
Expand All @@ -1612,9 +1614,9 @@ def session_views_by_visibility(self) -> Tuple[List[SessionViewProtocol], List[S
if not sv:
continue
if sheet in selected_sheets:
visible_session_views.append(sv)
visible_session_views.add(sv)
else:
not_visible_session_views.append(sv)
not_visible_session_views.add(sv)
return visible_session_views, not_visible_session_views

# --- server request handlers --------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1693,7 +1695,8 @@ def m_textDocument_publishDiagnostics(self, params: PublishDiagnosticsParams) ->
mgr.on_diagnostics_updated()
sb = self.get_session_buffer_for_uri_async(uri)
if sb:
sb.on_diagnostics_async(diagnostics, params.get("version"))
visible_session_views, _ = self.session_views_by_visibility()
sb.on_diagnostics_async(diagnostics, params.get("version"), visible_session_views)

def m_client_registerCapability(self, params: Any, request_id: Any) -> None:
"""handles the client/registerCapability request"""
Expand Down
5 changes: 0 additions & 5 deletions plugin/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,11 +340,6 @@ def region_to_range(view: sublime.View, region: sublime.Region) -> Range:
}


def is_range_equal(lhs: Range, rhs: Range) -> bool:
return lhs['start']['line'] == rhs['start']['line'] and lhs['start']['character'] == rhs['start']['character'] and \
lhs['end']['line'] == rhs['end']['line'] and lhs['end']['character'] == rhs['end']['character']


def to_encoded_filename(path: str, position: Position) -> str:
# WARNING: Cannot possibly do UTF-16 conversion :) Oh well.
return '{}:{}:{}'.format(path, position['line'] + 1, position['character'] + 1)
Expand Down
15 changes: 14 additions & 1 deletion plugin/core/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from .transports import create_transport
from .types import ClientConfig
from .types import matches_pattern
from .types import sublime_pattern_to_glob
from .typing import Optional, Any, Dict, Deque, List, Generator, Tuple, Union
from .url import parse_uri
from .views import extract_variables
Expand Down Expand Up @@ -370,7 +371,19 @@ def should_present_diagnostics(self, uri: DocumentUri) -> Optional[str]:
return "matches a pattern in binary_file_patterns"
if matches_pattern(path, settings.get("file_exclude_patterns")):
return "matches a pattern in file_exclude_patterns"
if matches_pattern(path, settings.get("folder_exclude_patterns")):
patterns = [sublime_pattern_to_glob(pattern, True) for pattern in settings.get("folder_exclude_patterns") or []]
project_data = self.window.project_data()
if project_data:
for folder in project_data.get('folders', []):
for pattern in folder.get('folder_exclude_patterns', []):
if pattern.startswith('//'):
patterns.append(sublime_pattern_to_glob(pattern, True, folder['path']))
elif pattern.startswith('/'):
patterns.append(sublime_pattern_to_glob(pattern, True))
else:
patterns.append(sublime_pattern_to_glob('//' + pattern, True, folder['path']))
patterns.append(sublime_pattern_to_glob('//**/' + pattern, True, folder['path']))
if matches_pattern(path, patterns):
return "matches a pattern in folder_exclude_patterns"
return None

Expand Down
37 changes: 21 additions & 16 deletions plugin/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,9 @@ def diagnostics_touching_point_async(
result.append((sb, intersections))
return result, covering

def on_diagnostics_updated_async(self) -> None:
def on_diagnostics_updated_async(self, is_view_visible: bool) -> None:
self._clear_code_actions_annotation()
if userprefs().show_code_actions:
if is_view_visible and userprefs().show_code_actions:
self._do_code_actions_async()
self._update_diagnostic_in_status_bar_async()
self._update_inline_diagnostics_async()
Expand Down Expand Up @@ -367,22 +367,27 @@ def get_language_id(self) -> str:
def on_load_async(self) -> None:
if not self._registered and is_regular_view(self.view):
self._register_async()
return
self.on_activated_async()

def on_activated_async(self) -> None:
if not self.view.is_loading() and is_regular_view(self.view):
if not self._registered:
self._register_async()
for sv in self.session_views_async():
if sv.code_lenses_needs_refresh:
sv.set_code_lenses_pending_refresh(False)
sv.start_code_lenses_async()
for sb in self.session_buffers_async():
if sb.semantic_tokens.needs_refresh:
sb.set_semantic_tokens_pending_refresh(False)
sb.do_semantic_tokens_async(self.view)
if sb.inlay_hints_needs_refresh:
sb.set_inlay_hints_pending_refresh(False)
sb.do_inlay_hints_async(self.view)
if self.view.is_loading() or not is_regular_view(self.view):
return
if not self._registered:
self._register_async()
if userprefs().show_code_actions:
self._do_code_actions_async()
for sv in self.session_views_async():
if sv.code_lenses_needs_refresh:
sv.set_code_lenses_pending_refresh(False)
sv.start_code_lenses_async()
for sb in self.session_buffers_async():
if sb.semantic_tokens.needs_refresh:
sb.set_semantic_tokens_pending_refresh(False)
sb.do_semantic_tokens_async(self.view)
if sb.inlay_hints_needs_refresh:
sb.set_inlay_hints_pending_refresh(False)
sb.do_inlay_hints_async(self.view)

def on_selection_modified_async(self) -> None:
different, current_region = self._update_stored_region_async()
Expand Down
31 changes: 13 additions & 18 deletions plugin/session_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from .core.views import document_color_params
from .core.views import DOCUMENT_LINK_FLAGS
from .core.views import entire_content_range
from .core.views import is_range_equal
from .core.views import lsp_color_to_phantom
from .core.views import MissingUriError
from .core.views import range_to_region
Expand Down Expand Up @@ -389,14 +388,16 @@ def get_document_link_at_point(self, view: sublime.View, point: int) -> Optional
def update_document_link(self, new_link: DocumentLink) -> None:
new_link_range = new_link["range"]
for link in self.document_links:
if is_range_equal(link["range"], new_link_range):
if link["range"] == new_link_range:
self.document_links.remove(link)
self.document_links.append(new_link)
break

# --- textDocument/publishDiagnostics ------------------------------------------------------------------------------

def on_diagnostics_async(self, raw_diagnostics: List[Diagnostic], version: Optional[int]) -> None:
def on_diagnostics_async(
self, raw_diagnostics: List[Diagnostic], version: Optional[int], visible_session_views: Set[SessionViewProtocol]
) -> None:
data_per_severity = {} # type: Dict[Tuple[int, bool], DiagnosticSeverityData]
view = self.some_view()
if view is None:
Expand All @@ -422,17 +423,24 @@ def on_diagnostics_async(self, raw_diagnostics: List[Diagnostic], version: Optio
else:
data.regions.append(region)
diagnostics.append((diagnostic, region))
self._publish_diagnostics_to_session_views(diagnostics_version, diagnostics, data_per_severity)
self._publish_diagnostics_to_session_views(
diagnostics_version, diagnostics, data_per_severity, visible_session_views)

def _publish_diagnostics_to_session_views(
self,
diagnostics_version: int,
diagnostics: List[Tuple[Diagnostic, sublime.Region]],
data_per_severity: Dict[Tuple[int, bool], DiagnosticSeverityData],
visible_session_views: Set[SessionViewProtocol],
) -> None:

def present() -> None:
self._present_diagnostics_async(diagnostics_version, diagnostics, data_per_severity)
self.diagnostics_version = diagnostics_version
self.diagnostics = diagnostics
self.data_per_severity = data_per_severity
self.diagnostics_are_visible = bool(diagnostics)
for sv in self.session_views:
sv.present_diagnostics_async(sv in visible_session_views)

self.diagnostics_debouncer.cancel_pending()

Expand All @@ -457,19 +465,6 @@ def present() -> None:
async_thread=True
)

def _present_diagnostics_async(
self,
diagnostics_version: int,
diagnostics: List[Tuple[Diagnostic, sublime.Region]],
data_per_severity: Dict[Tuple[int, bool], DiagnosticSeverityData],
) -> None:
self.diagnostics_version = diagnostics_version
self.diagnostics = diagnostics
self.data_per_severity = data_per_severity
self.diagnostics_are_visible = bool(diagnostics)
for sv in self.session_views:
sv.present_diagnostics_async()

# --- textDocument/semanticTokens ----------------------------------------------------------------------------------

def do_semantic_tokens_async(self, view: sublime.View, only_viewport: bool = False) -> None:
Expand Down
4 changes: 2 additions & 2 deletions plugin/session_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def diagnostics_tag_scope(self, tag: int) -> Optional[str]:
return 'markup.{}.lsp'.format(k.lower())
return None

def present_diagnostics_async(self) -> None:
def present_diagnostics_async(self, is_view_visible: bool) -> None:
flags = userprefs().diagnostics_highlight_style_flags() # for single lines
multiline_flags = None if userprefs().show_multiline_diagnostics_highlights else sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE # noqa: E501
level = userprefs().show_diagnostics_severity_level
Expand All @@ -282,7 +282,7 @@ def present_diagnostics_async(self) -> None:
self._draw_diagnostics(sev, level, multiline_flags or DIAGNOSTIC_SEVERITY[sev - 1][5], True)
listener = self.listener()
if listener:
listener.on_diagnostics_updated_async()
listener.on_diagnostics_updated_async(is_view_visible)

def _draw_diagnostics(self, severity: int, max_severity_level: int, flags: int, multiline: bool) -> None:
ICON_FLAGS = sublime.HIDE_ON_MINIMAP | sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE
Expand Down

0 comments on commit 9b9fc0b

Please sign in to comment.