"""Alias suggestion command.""" import os from pathlib import Path from typing import Optional import click from rich.console import Console from shellhist.core import HistoryLoader from shellhist.core.export import generate_alias, generate_alias_name from shellhist.core.patterns import detect_common_sequences @click.command("suggest-aliases") @click.option( "--history", "-H", type=str, help="Path to history file", ) @click.option( "--auto-create", "-a", is_flag=True, default=False, help="Automatically create aliases without prompting", ) @click.option( "--dry-run", "-n", is_flag=True, default=False, help="Preview aliases without creating them", ) @click.option( "--shell-file", "-f", type=str, help="Shell config file to append to (default: ~/.bashrc or ~/.zshrc)", ) @click.option( "--shell", "-s", type=click.Choice(["bash", "zsh"]), help="Shell type for parsing", ) @click.option( "--min-occurrences", "-m", type=int, default=3, help="Minimum occurrences for pattern (default: 3)", ) @click.pass_context def suggest_aliases_command( ctx: click.Context, history: Optional[str], auto_create: bool, dry_run: bool, shell_file: Optional[str], shell: Optional[str], min_occurrences: int, ) -> None: """Suggest shell aliases for detected command patterns. Examples: \b shellhist suggest-aliases shellhist suggest-aliases --auto-create shellhist suggest-aliases --dry-run --shell-file ~/.bashrc """ console = Console() try: loader = HistoryLoader(history_path=history) store = loader.load() if not store.entries: console.print("[yellow]No entries found in history.[/yellow]") return sequences = detect_common_sequences( store, max_length=4, min_occurrences=min_occurrences, ) if not sequences: console.print( f"[yellow]No significant patterns found with minimum {min_occurrences} occurrences.[/yellow]" ) console.print("Try lowering --min-occurrences or run more commands.") return shell_type = shell or ("zsh" if "zsh" in os.environ.get("SHELL", "") else "bash") if shell_file is None: home = os.path.expanduser("~") shell_file = f"{home}/.bashrc" if shell_type == "bash" else f"{home}/.zshrc" console.print(f"[bold cyan]Detected Patterns for Alias Suggestions[/bold cyan]\n") aliases_to_create = [] for i, pattern in enumerate(sequences[:10], 1): alias_name = generate_alias_name(pattern) alias_line = generate_alias(pattern, alias_name) console.print(f"{i}. [cyan]{alias_name}[/cyan]") console.print(f" Command: {' -> '.join(pattern.commands)}") console.print(f" Alias: {alias_line}") console.print(f" Frequency: {pattern.frequency} times\n") if dry_run: continue if auto_create: aliases_to_create.append(alias_line) else: if click.confirm(f"Create alias '{alias_name}'?", default=True): aliases_to_create.append(alias_line) if not aliases_to_create: console.print("\n[yellow]No aliases selected for creation.[/yellow]") return if dry_run: console.print("\n[bold]Aliases to create (dry-run):[/bold]") for alias in aliases_to_create: console.print(f" {alias}") return shell_path = Path(shell_file) shell_path.parent.mkdir(parents=True, exist_ok=True) with open(shell_file, "a", encoding="utf-8") as f: f.write("\n# Shell History Automation Tool - Generated Aliases\n") for alias in aliases_to_create: f.write(f"{alias}\n") console.print( f"\n[green]Successfully added {len(aliases_to_create)} aliases to {shell_file}[/green]" ) console.print("Run 'source " + shell_file + "' or restart your shell to use them.") except FileNotFoundError as e: console.print(f"[red]Error: {e}[/red]") ctx.exit(1) except Exception as e: console.print(f"[red]Error suggesting aliases: {e}[/red]") ctx.exit(1)