Skip to content

Commit

Permalink
Add context menu entry in log panel for toggling lines limit (#2047)
Browse files Browse the repository at this point in the history
  • Loading branch information
rchl authored Sep 10, 2022
1 parent 53cea14 commit 4274fb2
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 10 deletions.
7 changes: 6 additions & 1 deletion Context LSP Log Panel.sublime-menu
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
[
{
"caption": "Clear",
"command": "lsp_clear_log_panel",
"caption": "Clear Log Panel"
},
{
"caption": "Limit to 500 Lines",
"command": "lsp_toggle_log_panel_lines_limit",
"checkbox": true
},
{
"caption": "-"
Expand Down
1 change: 1 addition & 0 deletions boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .plugin.core.panels import destroy_output_panels
from .plugin.core.panels import LspClearLogPanelCommand
from .plugin.core.panels import LspClearPanelCommand
from .plugin.core.panels import LspToggleLogPanelLinesLimitCommand
from .plugin.core.panels import LspUpdatePanelCommand
from .plugin.core.panels import LspUpdateLogPanelCommand
from .plugin.core.panels import WindowPanelListener
Expand Down
44 changes: 37 additions & 7 deletions plugin/core/panels.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
import sublime_plugin


# about 80 chars per line implies maintaining a buffer of about 40kb per window
LOG_PANEL_MAX_LINES = 500

OUTPUT_PANEL_SETTINGS = {
"auto_indent": False,
"draw_indent_guides": False,
Expand Down Expand Up @@ -114,16 +111,47 @@ def create_panel(window: sublime.Window, name: str, result_file_regex: str, resu
return panel


def get_panel(window: Optional[sublime.Window], panel_name: str) -> Optional[sublime.View]:
if not window:
return None
return window.find_output_panel(panel_name)


def is_panel_open(window: sublime.Window, panel_name: str) -> bool:
return window.is_valid() and window.active_panel() == "output.{}".format(panel_name)


def ensure_panel(window: sublime.Window, name: str, result_file_regex: str, result_line_regex: str,
syntax: str, context_menu: Optional[str] = None) -> Optional[sublime.View]:
return window.find_output_panel(name) or \
return get_panel(window, name) or \
create_panel(window, name, result_file_regex, result_line_regex, syntax, context_menu)


class LspToggleLogPanelLinesLimitCommand(sublime_plugin.TextCommand):
SETTING_NAME = 'lsp_limit_lines'
MAX_LINES_LIMIT_ON = 500
MAX_LINES_LIMIT_OFF = 10000

@classmethod
def is_limit_enabled(cls, window: Optional[sublime.Window]) -> bool:
panel = get_panel(window, PanelName.Log)
return bool(panel and panel.settings().get(cls.SETTING_NAME, True))

@classmethod
def get_lines_limit(cls, window: Optional[sublime.Window]) -> int:
return cls.MAX_LINES_LIMIT_ON if cls.is_limit_enabled(window) else cls.MAX_LINES_LIMIT_OFF

def run(self, edit: sublime.Edit) -> None:
window = self.view.window()
panel = get_panel(window, PanelName.Log)
if panel:
settings = panel.settings()
settings.set(self.SETTING_NAME, not self.is_limit_enabled(window))

def is_checked(self) -> bool:
return self.is_limit_enabled(self.view.window())


class LspClearPanelCommand(sublime_plugin.TextCommand):
"""
A clear_panel command to clear the error panel.
Expand Down Expand Up @@ -162,9 +190,10 @@ def log_server_message(window: sublime.Window, prefix: str, message: str) -> Non
return
WindowPanelListener.server_log_map[window_id].append((prefix, message))
list_len = len(WindowPanelListener.server_log_map[window_id])
if list_len >= LOG_PANEL_MAX_LINES:
max_lines = LspToggleLogPanelLinesLimitCommand.get_lines_limit(window)
if list_len >= max_lines:
# Trim leading items in the list, leaving only the max allowed count.
del WindowPanelListener.server_log_map[window_id][:list_len - LOG_PANEL_MAX_LINES]
del WindowPanelListener.server_log_map[window_id][:list_len - max_lines]
panel = ensure_log_panel(window)
if is_panel_open(window, PanelName.Log) and panel:
update_log_panel(panel, window_id)
Expand All @@ -188,7 +217,8 @@ def run(self, edit: sublime.Edit, window_id: int) -> None:
self.view.insert(edit, self.view.size(), ''.join(new_lines))
last_region_end = 0 # Starting from point 0 in the panel ...
total_lines, _ = self.view.rowcol(self.view.size())
for _ in range(0, max(0, total_lines - LOG_PANEL_MAX_LINES)):
max_lines = LspToggleLogPanelLinesLimitCommand.get_lines_limit(self.view.window())
for _ in range(0, max(0, total_lines - max_lines)):
# ... collect all regions that span an entire line ...
region = self.view.full_line(last_region_end)
last_region_end = region.b
Expand Down
4 changes: 2 additions & 2 deletions tests/test_server_panel_circular.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from LSP.plugin.core.panels import ensure_log_panel
from LSP.plugin.core.panels import LOG_PANEL_MAX_LINES
from LSP.plugin.core.panels import log_server_message
from LSP.plugin.core.panels import LspToggleLogPanelLinesLimitCommand
from unittesting import DeferrableTestCase
import sublime

Expand Down Expand Up @@ -29,7 +29,7 @@ def update_panel(self, msg: str) -> None:
log_server_message(self.window, "test", msg)

def test_server_panel_circular_behavior(self):
n = LOG_PANEL_MAX_LINES
n = LspToggleLogPanelLinesLimitCommand.MAX_LINES_LIMIT_ON
for i in range(0, n + 1):
self.update_panel(str(i))
self.update_panel("overflow")
Expand Down

0 comments on commit 4274fb2

Please sign in to comment.