"""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)