"""Output formatting with Rich.""" from rich.console import Console from rich.panel import Panel from rich.syntax import Syntax from rich.text import Text from rich.theme import Theme from shell_speak.models import CommandMatch, HistoryEntry from shell_speak.nlp import tokenize custom_theme = Theme({ "command": "bold cyan", "keyword": "bold green", "tool": "bold magenta", "explanation": "italic", "error": "bold red", "warning": "yellow", "success": "bold green", "info": "blue", }) console = Console(theme=custom_theme) def display_command(match: CommandMatch, explain: bool = False) -> None: """Display a command match with rich formatting.""" syntax = Syntax(match.command, "bash", theme="monokai", line_numbers=False) title = f"[tool]{match.pattern.tool}[/tool] command" panel = Panel( syntax, title=title, expand=False, border_style="cyan", ) console.print(panel) if explain or match.confidence < 0.8: confidence_pct = int(match.confidence * 100) confidence_color = "success" if match.confidence >= 0.8 else "warning" if match.confidence >= 0.5 else "error" console.print(f"Confidence: [{confidence_color}]{confidence_pct}%[/]") if match.explanation: console.print(f"\n[explanation]{match.explanation}[/]") if explain: _show_detailed_explanation(match) def _show_detailed_explanation(match: CommandMatch) -> None: """Show detailed breakdown of a command.""" console.print("\n[info]Command breakdown:[/]") tokens = tokenize(match.command) for token in tokens: if token in ("docker", "kubectl", "git", "ls", "cd", "cat", "grep", "find", "rm", "cp", "mv"): console.print(f" [keyword]{token}[/]", end=" ") else: console.print(f" {token}", end=" ") def display_error(message: str) -> None: """Display an error message.""" console.print(f"[error]Error:[/] {message}") def display_warning(message: str) -> None: """Display a warning message.""" console.print(f"[warning]Warning:[/] {message}") def display_info(message: str) -> None: """Display an info message.""" console.print(f"[info]{message}[/]") def display_history(entries: list[HistoryEntry], limit: int = 20) -> None: """Display command history.""" console.print(f"\n[info]Command History (last {limit}):[/]\n") for i, entry in enumerate(entries[-limit:], 1): timestamp = entry.timestamp.strftime("%Y-%m-%d %H:%M") console.print(f"{i}. [tool]{entry.tool}[/tool] | {timestamp}") console.print(f" Query: {entry.query}") console.print(f" [command]{entry.command}[/]") console.print() def display_suggestions(suggestions: list[str]) -> None: """Display command suggestions.""" if not suggestions: return console.print("\n[info]Did you mean?[/]") for i, suggestion in enumerate(suggestions[:5], 1): console.print(f" {i}. {suggestion}") def display_learn_success(query: str, command: str) -> None: """Display confirmation of learning.""" console.print("[success]Learned new command:[/]") console.print(f" Query: {query}") console.print(f" [command]{command}[/]") def display_forget_success(query: str) -> None: """Display confirmation of forgetting a pattern.""" console.print(f"[success]Forgot pattern for:[/] {query}") def display_help_header() -> None: """Display the help header.""" console.print(Panel( Text("Shell Speak - Natural Language to Shell Commands", justify="center", style="bold cyan"), subtitle="Type a description of what you want to do", expand=False, ))