|
1 | | -"""``orca completion`` — generate shell auto-completion scripts.""" |
| 1 | +"""``orca completion`` — install shell auto-completion or print instructions.""" |
2 | 2 |
|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
5 | 5 | import click |
6 | 6 | from rich.console import Console |
7 | 7 |
|
| 8 | +from orca_cli.core.shell_completion import ( |
| 9 | + SUPPORTED_SHELLS, |
| 10 | + detect_shell, |
| 11 | + install_completion, |
| 12 | +) |
| 13 | + |
8 | 14 | console = Console() |
9 | 15 |
|
10 | 16 | INSTRUCTIONS = { |
|
23 | 29 | } |
24 | 30 |
|
25 | 31 |
|
26 | | -@click.command() |
27 | | -@click.argument("shell", type=click.Choice(["bash", "zsh", "fish"], case_sensitive=False)) |
28 | | -def completion(shell: str) -> None: |
29 | | - """Generate shell completion script and display installation instructions. |
30 | | -
|
31 | | - Supported shells: bash, zsh, fish. |
32 | | - """ |
33 | | - shell = shell.lower() |
| 32 | +def _print_instructions(shell: str) -> None: |
34 | 33 | console.print(f"\n[bold cyan]Shell completion for {shell}[/bold cyan]\n") |
35 | 34 | console.print(INSTRUCTIONS[shell]) |
36 | | - console.print() |
| 35 | + console.print( |
| 36 | + f"\n[dim]Or run 'orca completion install {shell}' " |
| 37 | + f"to install automatically.[/dim]\n" |
| 38 | + ) |
| 39 | + |
| 40 | + |
| 41 | +class _CompletionGroup(click.Group): |
| 42 | + """Group that accepts a bare shell name as shorthand for ``show <shell>``. |
| 43 | +
|
| 44 | + Lets users keep the legacy ``orca completion bash`` UX while also exposing |
| 45 | + the newer ``orca completion install <shell>`` subcommand. |
| 46 | + """ |
| 47 | + |
| 48 | + def resolve_command(self, ctx, args): |
| 49 | + if args and args[0].lower() in SUPPORTED_SHELLS: |
| 50 | + return super().resolve_command(ctx, ["show", *args]) |
| 51 | + return super().resolve_command(ctx, args) |
| 52 | + |
| 53 | + |
| 54 | +@click.group(cls=_CompletionGroup, invoke_without_command=True) |
| 55 | +@click.pass_context |
| 56 | +def completion(ctx: click.Context) -> None: |
| 57 | + """Shell completion: print instructions or install automatically. |
| 58 | +
|
| 59 | + \b |
| 60 | + Examples: |
| 61 | + orca completion # auto-detect shell, print instructions |
| 62 | + orca completion bash # print instructions for bash (legacy) |
| 63 | + orca completion show zsh # same, explicit |
| 64 | + orca completion install # auto-detect shell, install |
| 65 | + orca completion install fish # install for fish |
| 66 | + """ |
| 67 | + if ctx.invoked_subcommand is not None: |
| 68 | + return |
| 69 | + # Bare ``orca completion`` → auto-detect + print |
| 70 | + detected = detect_shell() |
| 71 | + if not detected: |
| 72 | + console.print( |
| 73 | + "[yellow]Could not auto-detect your shell.[/yellow] " |
| 74 | + "Pass one explicitly: [cyan]orca completion <bash|zsh|fish>[/cyan]." |
| 75 | + ) |
| 76 | + ctx.exit(1) |
| 77 | + _print_instructions(detected) |
| 78 | + |
| 79 | + |
| 80 | +@completion.command("show") |
| 81 | +@click.argument("shell", required=False, |
| 82 | + type=click.Choice(list(SUPPORTED_SHELLS), case_sensitive=False)) |
| 83 | +@click.pass_context |
| 84 | +def completion_show(ctx: click.Context, shell: str | None) -> None: |
| 85 | + """Print manual installation instructions for the given shell.""" |
| 86 | + resolved = shell.lower() if shell else detect_shell() |
| 87 | + if not resolved: |
| 88 | + console.print( |
| 89 | + "[yellow]Could not auto-detect your shell.[/yellow] " |
| 90 | + "Pass one explicitly: [cyan]orca completion show <bash|zsh|fish>[/cyan]." |
| 91 | + ) |
| 92 | + ctx.exit(1) |
| 93 | + _print_instructions(resolved) |
| 94 | + |
| 95 | + |
| 96 | +@completion.command("install") |
| 97 | +@click.argument("shell", required=False, |
| 98 | + type=click.Choice(list(SUPPORTED_SHELLS), case_sensitive=False)) |
| 99 | +@click.pass_context |
| 100 | +def completion_install(ctx: click.Context, shell: str | None) -> None: |
| 101 | + """Install orca shell completion (auto-detects shell when omitted). |
| 102 | +
|
| 103 | + \b |
| 104 | + - bash/zsh: appends an eval line to ~/.bashrc / ~/.zshrc (idempotent). |
| 105 | + - fish: writes ~/.config/fish/completions/orca.fish. |
| 106 | + """ |
| 107 | + resolved = shell.lower() if shell else detect_shell() |
| 108 | + if not resolved: |
| 109 | + console.print( |
| 110 | + "[red]Could not auto-detect your shell.[/red] " |
| 111 | + "Pass one explicitly: [cyan]orca completion install <bash|zsh|fish>[/cyan]." |
| 112 | + ) |
| 113 | + ctx.exit(1) |
| 114 | + msg = install_completion(resolved) |
| 115 | + console.print(f"[green]✓ {msg}[/green]") |
0 commit comments