4
4
from .completion import QueryCompletionsTask
5
5
from .core .constants import HOVER_ENABLED_KEY
6
6
from .core .logging import debug
7
+ from .core .open import open_in_browser
7
8
from .core .panels import PanelName
8
9
from .core .protocol import Diagnostic
9
10
from .core .protocol import DiagnosticSeverity
27
28
from .core .settings import userprefs
28
29
from .core .signature_help import SigHelp
29
30
from .core .types import basescope2languageid
31
+ from .core .types import ClientConfig
30
32
from .core .types import debounced
31
33
from .core .types import DebouncerNonThreadSafe
32
34
from .core .types import FEATURES_TIMEOUT
40
42
from .core .views import DOCUMENT_HIGHLIGHT_KINDS
41
43
from .core .views import first_selection_region
42
44
from .core .views import format_code_actions_for_quick_panel
45
+ from .core .views import format_diagnostic_for_html
43
46
from .core .views import make_link
44
47
from .core .views import MarkdownLangMap
45
48
from .core .views import range_to_region
@@ -176,7 +179,8 @@ def _setup(self) -> None:
176
179
self ._stored_selection = []
177
180
self ._sighelp = None # type: Optional[SigHelp]
178
181
self ._lightbulb_line = None # type: Optional[int]
179
- self ._actions_by_config = [] # type: List[CodeActionsByConfigName]
182
+ self ._diagnostics_for_selection = [] # type: List[Tuple[SessionBufferProtocol, List[Diagnostic]]]
183
+ self ._code_actions_for_selection = [] # type: List[CodeActionsByConfigName]
180
184
self ._registered = False
181
185
182
186
def _cleanup (self ) -> None :
@@ -471,17 +475,40 @@ def on_hover(self, point: int, hover_zone: int) -> None:
471
475
if hover_zone == sublime .HOVER_TEXT and window and window .settings ().get (HOVER_ENABLED_KEY , True ):
472
476
self .view .run_command ("lsp_hover" , {"point" : point })
473
477
elif hover_zone == sublime .HOVER_GUTTER :
474
- # Lightbulb must be visible and at the same line
475
- if self ._lightbulb_line != self .view .rowcol (point )[0 ]:
476
- return
477
- content = code_actions_content (self ._actions_by_config )
478
+ sublime .set_timeout_async (partial (self ._on_hover_gutter_async , point ))
479
+
480
+ def _on_hover_gutter_async (self , point : int ) -> None :
481
+ content = ''
482
+ if self ._lightbulb_line == self .view .rowcol (point )[0 ]:
483
+ content += code_actions_content (self ._code_actions_for_selection )
484
+ if userprefs ().show_diagnostics_severity_level :
485
+ diagnostics_with_config = [] # type: List[Tuple[ClientConfig, Diagnostic]]
486
+ diagnostics_by_session_buffer = [] # type: List[Tuple[SessionBufferProtocol, List[Diagnostic]]]
487
+ max_severity_level = min (userprefs ().show_diagnostics_severity_level , DiagnosticSeverity .Information )
488
+ if userprefs ().diagnostics_gutter_marker :
489
+ diagnostics_by_session_buffer = self .diagnostics_intersecting_async (self .view .line (point ))[0 ]
490
+ elif content :
491
+ diagnostics_by_session_buffer = self ._diagnostics_for_selection
478
492
if content :
479
- show_lsp_popup (
480
- self .view ,
481
- content ,
482
- flags = sublime .HIDE_ON_MOUSE_MOVE_AWAY ,
483
- location = point ,
484
- on_navigate = lambda href : self ._on_navigate (href , point ))
493
+ max_severity_level = userprefs ().show_diagnostics_severity_level
494
+ for sb , diagnostics in diagnostics_by_session_buffer :
495
+ diagnostics_with_config .extend (
496
+ (sb .session .config , diagnostic ) for diagnostic in diagnostics
497
+ if diagnostic_severity (diagnostic ) <= max_severity_level
498
+ )
499
+ if diagnostics_with_config :
500
+ diagnostics_with_config .sort (key = lambda d : diagnostic_severity (d [1 ]))
501
+ content += '<div class="diagnostics">'
502
+ for config , diagnostic in diagnostics_with_config :
503
+ content += format_diagnostic_for_html (config , diagnostic )
504
+ content += '</div>'
505
+ if content :
506
+ show_lsp_popup (
507
+ self .view ,
508
+ content ,
509
+ flags = sublime .HIDE_ON_MOUSE_MOVE_AWAY ,
510
+ location = point ,
511
+ on_navigate = lambda href : self ._on_navigate (href , point ))
485
512
486
513
def on_text_command (self , command_name : str , args : Optional [dict ]) -> Optional [Tuple [str , dict ]]:
487
514
if command_name == "auto_complete" :
@@ -638,13 +665,13 @@ def _on_sighelp_navigate(self, href: str) -> None:
638
665
def _do_code_actions_async (self ) -> None :
639
666
if not self ._stored_selection :
640
667
return
641
- diagnostics_by_config , covering = self .diagnostics_intersecting_async (self ._stored_selection [0 ])
668
+ self . _diagnostics_for_selection , covering = self .diagnostics_intersecting_async (self ._stored_selection [0 ])
642
669
actions_manager \
643
- .request_for_region_async (self .view , covering , diagnostics_by_config , manual = False ) \
670
+ .request_for_region_async (self .view , covering , self . _diagnostics_for_selection , manual = False ) \
644
671
.then (self ._on_code_actions )
645
672
646
673
def _on_code_actions (self , responses : List [CodeActionsByConfigName ]) -> None :
647
- self ._actions_by_config = responses
674
+ self ._code_actions_for_selection = responses
648
675
action_count = 0
649
676
first_action_title = ''
650
677
for _ , actions in responses :
@@ -678,8 +705,8 @@ def _on_code_actions(self, responses: List[CodeActionsByConfigName]) -> None:
678
705
)
679
706
680
707
def _on_code_actions_annotation_click (self , href : str ) -> None :
681
- if href == 'code-actions:' and self ._actions_by_config :
682
- self .view .run_command ('lsp_code_actions' , {'code_actions_by_config' : self ._actions_by_config })
708
+ if href == 'code-actions:' and self ._code_actions_for_selection :
709
+ self .view .run_command ('lsp_code_actions' , {'code_actions_by_config' : self ._code_actions_for_selection })
683
710
684
711
def _clear_code_actions_annotation (self ) -> None :
685
712
self .view .erase_regions (SessionView .CODE_ACTIONS_KEY )
@@ -688,7 +715,7 @@ def _clear_code_actions_annotation(self) -> None:
688
715
def _on_navigate (self , href : str , point : int ) -> None :
689
716
if href .startswith ('code-actions:' ):
690
717
_ , config_name = href .split (":" )
691
- actions = next (actions for name , actions in self ._actions_by_config if name == config_name )
718
+ actions = next (actions for name , actions in self ._code_actions_for_selection if name == config_name )
692
719
if len (actions ) > 1 :
693
720
window = self .view .window ()
694
721
if window :
@@ -701,6 +728,8 @@ def _on_navigate(self, href: str, point: int) -> None:
701
728
placeholder = "Code actions" )
702
729
else :
703
730
self .handle_code_action_select (config_name , actions , 0 )
731
+ else :
732
+ open_in_browser (href )
704
733
705
734
def handle_code_action_select (self , config_name : str , actions : List [CodeActionOrCommand ], index : int ) -> None :
706
735
if index == - 1 :
0 commit comments