Skip to content

Commit 7d860d8

Browse files
authored
feat(cli): add shell completion for bash, zsh, and fish (#31)
## Summary - New `vaultctl completion <shell>` command (bash, zsh, fish) - Uses Click's `shell_completion` API - Works without `.vaultctl.yml` config ## Install ```bash eval "$(vaultctl completion bash)" # bash eval "$(vaultctl completion zsh)" # zsh vaultctl completion fish > ~/.config/fish/completions/vaultctl.fish # fish ``` ## Test plan - [ ] `vaultctl completion bash` outputs valid bash completion - [ ] `vaultctl completion zsh` outputs valid zsh completion - [ ] `vaultctl completion fish` outputs valid fish completion - [ ] Tab completion works after eval Co-authored-by: Fred Thiele <8555720+f3rdy@users.noreply.github.com>
1 parent 99df951 commit 7d860d8

1 file changed

Lines changed: 28 additions & 1 deletion

File tree

src/vaultctl/cli.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def main(ctx: click.Context, config_path: str | None, vault_file: str | None) ->
6161
cfg_path = Path(config_path) if config_path else find_config()
6262

6363
if cfg_path is None:
64-
if ctx.invoked_subcommand in ("init", "self-update"):
64+
if ctx.invoked_subcommand in ("init", "self-update", "completion"):
6565
ctx.obj = VaultContext(VaultConfig())
6666
return
6767
click.echo("Error: No .vaultctl.yml found.", err=True)
@@ -780,6 +780,33 @@ def _print_expiry_warning(w: ExpiryWarning) -> None:
780780
click.echo(f" {w.key:<40} {w.expires} " + click.style(label, fg=color))
781781

782782

783+
@main.command()
784+
@click.argument("shell", type=click.Choice(["bash", "zsh", "fish"]))
785+
def completion(shell: str) -> None:
786+
"""Generate shell completion script.
787+
788+
\b
789+
Install (bash):
790+
eval "$(vaultctl completion bash)"
791+
vaultctl completion bash >> ~/.bashrc
792+
793+
Install (zsh):
794+
eval "$(vaultctl completion zsh)"
795+
vaultctl completion zsh >> ~/.zshrc
796+
797+
Install (fish):
798+
vaultctl completion fish > ~/.config/fish/completions/vaultctl.fish
799+
"""
800+
from click.shell_completion import get_completion_class
801+
802+
comp_cls = get_completion_class(shell)
803+
if comp_cls is None:
804+
click.echo(f"Error: Unsupported shell: {shell}", err=True)
805+
sys.exit(1)
806+
comp = comp_cls(main, {}, "vaultctl", "_VAULTCTL_COMPLETE")
807+
click.echo(comp.source())
808+
809+
783810
@main.command("self-update")
784811
@pass_ctx
785812
def self_update_cmd(_vctx: VaultContext) -> None:

0 commit comments

Comments
 (0)