0b43408a8d
- Add shared rendering helpers for width-aware tree labels, truncation, and no-wrap Rich text. - Preserve tab index and group window metadata through the extension and SDK factories. - Render tab trees in browser/window/index order with grouped tab details and optional shortened URLs. - Reuse the tab tree labels in window trees to keep output compact and consistent. - Cover legacy missing-index responses, grouped/collapsed tabs, URL display, and rendering helpers with tests.
56 lines
2.2 KiB
Python
56 lines
2.2 KiB
Python
"""Reusable rendering helpers for CLI command modules."""
|
|
from __future__ import annotations
|
|
|
|
import shutil
|
|
|
|
from rich.console import Console
|
|
from rich.text import Text
|
|
from rich.tree import Tree
|
|
|
|
def shorten(value: str | None, limit: int) -> str:
|
|
"""Return *value* shortened to *limit* cells-ish, using an ellipsis."""
|
|
value = value or ""
|
|
return value if len(value) <= limit else value[:max(0, limit - 1)] + "…"
|
|
|
|
def terminal_width(console: Console | None = None, *, fallback: int = 120) -> int:
|
|
"""Best-effort terminal width for interactive and redirected output.
|
|
|
|
Rich falls back to 80 columns when stdout is redirected. browser-cli output is
|
|
often piped into files for inspection, so also consult ``shutil``/``COLUMNS``
|
|
and prefer the wider value.
|
|
"""
|
|
rich_width = (console.width if console is not None else 0) or 0
|
|
shell_width = shutil.get_terminal_size((fallback, 20)).columns
|
|
return max(rich_width, shell_width)
|
|
|
|
def tree_title_limit(*, console: Console | None = None, show_browser: bool = False, show_urls: bool = False) -> int:
|
|
"""Title width for tree labels, reserving space for branches/IDs/metadata."""
|
|
reserve = 48 if show_urls else 32
|
|
if show_browser:
|
|
reserve += 4
|
|
return max(50, terminal_width(console) - reserve)
|
|
|
|
def tree_url_limit(title_limit: int, *, console: Console | None = None) -> int:
|
|
"""URL width for tree labels when URLs are displayed."""
|
|
return max(35, terminal_width(console) - title_limit - 40)
|
|
|
|
def no_wrap_text() -> Text:
|
|
"""Text configured for one-line tree labels with edge ellipsis."""
|
|
return Text(no_wrap=True, overflow="ellipsis")
|
|
|
|
def tab_tree_label(tab, *, title_limit: int, show_urls: bool = False, url_limit: int = 55) -> Text:
|
|
"""Reusable one-line label for a browser tab in tree views."""
|
|
label = no_wrap_text()
|
|
label.append(f"[{tab.id}] ", style="dim")
|
|
label.append(shorten(tab.title or "(untitled)", title_limit))
|
|
if tab.active:
|
|
label.append(" *", style="green")
|
|
if show_urls and tab.url:
|
|
label.append(" — ", style="dim")
|
|
label.append(shorten(tab.url, url_limit), style="dim")
|
|
return label
|
|
|
|
def print_tree(tree: Tree, *, console: Console | None = None) -> None:
|
|
"""Render a Rich tree using the detected full terminal width."""
|
|
Console(width=terminal_width(console)).print(tree)
|