Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add menu item to disable/enable hover popups #2316

Merged
merged 7 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
5 changes: 5 additions & 0 deletions Main.sublime-menu
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@
{
"caption": "LSP: Show Inlay Hints",
"command": "lsp_toggle_inlay_hints"
},
{
"caption": "LSP: Show Hover Popups",
"command": "lsp_toggle_hover_popups",
"checkbox": true
}
]
},
Expand Down
1 change: 1 addition & 0 deletions boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
from .plugin.hierarchy import LspHierarchyToggleCommand
from .plugin.hierarchy import LspTypeHierarchyCommand
from .plugin.hover import LspHoverCommand
from .plugin.hover import LspToggleHoverPopupsCommand
from .plugin.inlay_hint import LspInlayHintClickCommand
from .plugin.inlay_hint import LspToggleInlayHintsCommand
from .plugin.panels import LspClearLogPanelCommand
Expand Down
10 changes: 10 additions & 0 deletions plugin/core/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# TODO: Move all constants which are shared by multiple modules into this file, so that they can be imported without
# causing import loops

# Keys for View.add_regions
HOVER_HIGHLIGHT_KEY = 'lsp_hover_highlight'

# Setting keys
HOVER_ENABLED_KEY = 'lsp_show_hover_popups'
HOVER_PROVIDER_COUNT_KEY = 'lsp_hover_provider_count'
SHOW_DEFINITIONS_KEY = 'show_definitions'
3 changes: 3 additions & 0 deletions plugin/core/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,9 @@ def start_code_lenses_async(self) -> None:
def set_code_lenses_pending_refresh(self, needs_refresh: bool = True) -> None:
...

def reset_show_definitions(self) -> None:
...


class SessionBufferProtocol(Protocol):

Expand Down
4 changes: 3 additions & 1 deletion plugin/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from .code_actions import CodeActionOrCommand
from .code_actions import CodeActionsByConfigName
from .completion import QueryCompletionsTask
from .core.constants import HOVER_ENABLED_KEY
from .core.logging import debug
from .core.panels import PanelName
from .core.protocol import Diagnostic
Expand Down Expand Up @@ -466,7 +467,8 @@ def on_query_context(self, key: str, operator: int, operand: Any, match_all: boo
def on_hover(self, point: int, hover_zone: int) -> None:
if self.view.is_popup_visible():
return
if hover_zone == sublime.HOVER_TEXT:
window = self.view.window()
if hover_zone == sublime.HOVER_TEXT and window and window.settings().get(HOVER_ENABLED_KEY, True):
self.view.run_command("lsp_hover", {"point": point})
elif hover_zone == sublime.HOVER_GUTTER:
# Lightbulb must be visible and at the same line
Expand Down
38 changes: 37 additions & 1 deletion plugin/hover.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from .code_actions import actions_manager
from .code_actions import CodeActionOrCommand
from .code_actions import CodeActionsByConfigName
from .core.constants import HOVER_ENABLED_KEY
from .core.constants import HOVER_HIGHLIGHT_KEY
from .core.constants import HOVER_PROVIDER_COUNT_KEY
from .core.constants import SHOW_DEFINITIONS_KEY
from .core.open import lsp_range_from_uri_fragment
from .core.open import open_file_uri
from .core.open import open_in_browser
Expand All @@ -18,6 +22,7 @@
from .core.sessions import SessionBufferProtocol
from .core.settings import userprefs
from .core.typing import List, Optional, Dict, Tuple, Sequence, Union
from .core.typing import cast
from .core.url import parse_uri
from .core.views import diagnostic_severity
from .core.views import first_selection_region
Expand All @@ -35,12 +40,12 @@
from .core.views import text_document_position_params
from .core.views import unpack_href_location
from .core.views import update_lsp_popup
from .session_view import HOVER_HIGHLIGHT_KEY
from functools import partial
from urllib.parse import urlparse
import html
import mdpopups
import sublime
import sublime_plugin


SUBLIME_WORD_MASK = 515
Expand Down Expand Up @@ -385,3 +390,34 @@ def try_open_custom_uri_async(self, href: str) -> None:
for session in self.sessions():
if session.try_open_uri_async(href, r) is not None:
return


class LspToggleHoverPopupsCommand(sublime_plugin.WindowCommand):

def is_enabled(self) -> bool:
view = self.window.active_view()
if view:
return self._has_hover_provider(view)
return False

def is_checked(self) -> bool:
return bool(self.window.settings().get(HOVER_ENABLED_KEY, True))

def run(self) -> None:
enable = not self.is_checked()
self.window.settings().set(HOVER_ENABLED_KEY, enable)
sublime.set_timeout_async(partial(self._update_views_async, enable))

def _has_hover_provider(self, view: sublime.View) -> bool:
return cast(int, view.settings().get(HOVER_PROVIDER_COUNT_KEY, 0)) > 0

def _update_views_async(self, enable: bool) -> None:
window_manager = windows.lookup(self.window)
if not window_manager:
return
for session in window_manager.get_sessions():
for session_view in session.session_views_async():
if enable:
session_view.view.settings().set(SHOW_DEFINITIONS_KEY, False)
else:
session_view.reset_show_definitions()
25 changes: 16 additions & 9 deletions plugin/session_view.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from .code_lens import CodeLensView
from .core.active_request import ActiveRequest
from .core.constants import HOVER_ENABLED_KEY
from .core.constants import HOVER_HIGHLIGHT_KEY
from .core.constants import HOVER_PROVIDER_COUNT_KEY
from .core.constants import SHOW_DEFINITIONS_KEY
from .core.promise import Promise
from .core.protocol import CodeLens
from .core.protocol import CodeLensExtended
Expand All @@ -9,6 +13,7 @@
from .core.protocol import Request
from .core.sessions import AbstractViewListener
from .core.sessions import Session
from .core.settings import globalprefs
from .core.settings import userprefs
from .core.typing import Any, Iterable, List, Tuple, Optional, Dict, Generator
from .core.views import DIAGNOSTIC_SEVERITY
Expand All @@ -22,7 +27,6 @@
import sublime

DIAGNOSTIC_TAG_VALUES = [v for (k, v) in DiagnosticTag.__dict__.items() if not k.startswith('_')] # type: List[int]
HOVER_HIGHLIGHT_KEY = "lsp_hover_highlight"


class TagData:
Expand All @@ -39,9 +43,7 @@ class SessionView:
Holds state per session per view.
"""

SHOW_DEFINITIONS_KEY = "show_definitions"
HOVER_PROVIDER_KEY = "hoverProvider"
HOVER_PROVIDER_COUNT_KEY = "lsp_hover_provider_count"
AC_TRIGGERS_KEY = "auto_complete_triggers"
COMPLETION_PROVIDER_KEY = "completionProvider"
TRIGGER_CHARACTERS_KEY = "completionProvider.triggerCharacters"
Expand Down Expand Up @@ -224,20 +226,25 @@ def _apply_auto_complete_triggers(

def _increment_hover_count(self) -> None:
settings = self.view.settings()
count = settings.get(self.HOVER_PROVIDER_COUNT_KEY, 0)
count = settings.get(HOVER_PROVIDER_COUNT_KEY, 0)
if isinstance(count, int):
count += 1
settings.set(self.HOVER_PROVIDER_COUNT_KEY, count)
settings.set(self.SHOW_DEFINITIONS_KEY, False)
settings.set(HOVER_PROVIDER_COUNT_KEY, count)
window = self.view.window()
if window and window.settings().get(HOVER_ENABLED_KEY, True):
settings.set(SHOW_DEFINITIONS_KEY, False)

def _decrement_hover_count(self) -> None:
settings = self.view.settings()
count = settings.get(self.HOVER_PROVIDER_COUNT_KEY)
count = settings.get(HOVER_PROVIDER_COUNT_KEY)
if isinstance(count, int):
count -= 1
if count == 0:
settings.erase(self.HOVER_PROVIDER_COUNT_KEY)
settings.set(self.SHOW_DEFINITIONS_KEY, True)
settings.erase(HOVER_PROVIDER_COUNT_KEY)
self.reset_show_definitions()

def reset_show_definitions(self) -> None:
self.view.settings().set(SHOW_DEFINITIONS_KEY, globalprefs().get(SHOW_DEFINITIONS_KEY))
rchl marked this conversation as resolved.
Show resolved Hide resolved

def get_uri(self) -> Optional[DocumentUri]:
listener = self.listener()
Expand Down