# Shell Completion for `btr`
## How it works
The script emitted by `btr completions <shell>` has two layers:
**Static layer** (all shells) — generated by clap from the CLI grammar:
- All built-in subcommands: `build`, `test`, `run`, `dev`, `fmt`, `clean`, `ci`, `exec`, `parallel`, `validate`, `init`, `templates`, `workspace`, `watch`, `package`, `release`, `completions`, `schema`, `manpage`, `list`, `which`, `doctor`, `show`, `explain`.
- All flag names (`--dry-run`, `--safe`, `--json`, `--profile`, `--workspace`, `--log-dir`, etc.).
- Enum-typed flag values: `--template <TAB>` lists every starter template; `completions <TAB>` lists supported shells; `--order <TAB>` lists `path|name`.
- File/dir completion for path args (`--workspace`, `--log-dir`, `--template-file`, `--output`).
**Dynamic layer** (bash, zsh, fish only) — a small wrapper appended below the clap script that calls `btr complete <slot> --cwd "$PWD"` to fetch candidates that live in your `.btr.toml`:
| `btr exec <TAB>` | `commands` | `[commands]` keys |
| `btr show <TAB>` / `btr explain <TAB>` | `commands` | `[commands]` keys |
| `btr parallel <TAB>` | `commands` | `[commands]` keys |
| `btr --profile <TAB>` | `profiles` | `[profiles.*]` keys |
| `btr workspace --name <TAB>` | `workspace-names` | `project.name` of every `.btr.toml` under cwd |
| `btr workspace --tag <TAB>` | `workspace-tags` | `project.tags` deduped across the same tree |
PowerShell and Elvish get only the static layer — built-in subcommands and flags complete normally, but `btr exec <TAB>` will not list your custom command names.
Dynamic candidates are read by re-invoking `btr`, so:
- `btr` must be on `PATH` when you hit TAB.
- Candidates come from the `.btr.toml` discovered upward from the **current directory**, not from where the completion script was generated.
## Setup
### One-shot (any shell, from the installed binary)
The fastest path — works for users who installed via `cargo install btr` and
never cloned the repo:
```bash
btr install-completions # auto-detects from $SHELL
btr install-completions --shell zsh
btr install-completions --print-path # show where it would write
btr install-completions --dest ./btr.bash --shell bash
btr install-completions --shell bash --force # overwrite existing
btr install-completions --shell bash --no-hint # silence setup tips
```
Supports `bash`, `zsh`, `fish`. PowerShell and Elvish print the manual
command to run instead.
### Bash
```bash
# Prerequisites (Arch): sudo pacman -S bash-completion
# Ensure ~/.bashrc sources it:
# [ -r /usr/share/bash-completion/bash_completion ] && . /usr/share/bash-completion/bash_completion
mkdir -p ~/.local/share/bash-completion/completions
btr completions bash > ~/.local/share/bash-completion/completions/btr
exec bash # or open a new shell
```
System-wide alternative: write to `/etc/bash_completion.d/btr` (requires root).
Quick test without persisting:
```bash
eval "$(btr completions bash)"
btr exec <TAB><TAB>
```
### Zsh
```zsh
# Ensure ~/.zshrc runs:
# autoload -U compinit && compinit
# Either drop into an existing fpath dir:
btr completions zsh > "${fpath[1]}/_btr"
# Or use your own dir (add to fpath BEFORE compinit in ~/.zshrc):
mkdir -p ~/.zsh/completions
btr completions zsh > ~/.zsh/completions/_btr
# fpath=(~/.zsh/completions $fpath)
# autoload -U compinit && compinit
exec zsh
```
### Fish
```fish
mkdir -p ~/.config/fish/completions
btr completions fish > ~/.config/fish/completions/btr.fish
# Picked up automatically in the next session.
```
### PowerShell
```powershell
btr completions power-shell > $PROFILE.CurrentUserAllHosts
# Or dot-source into an existing profile:
# btr completions power-shell | Out-File btr-completion.ps1
# . ./btr-completion.ps1
```
### Elvish
```elvish
btr completions elvish > ~/.config/elvish/lib/btr-completion.elv
# Then in rc.elv: use btr-completion
```
### Via the installer
One-shot setup that installs `btr` and writes the completion file into your
shell's user dir with the conventional filename:
```bash
./install.sh --setup-completion # auto-detects from $SHELL
./install.sh --setup-completion=bash # or pick a shell explicitly
./install.sh --setup-completion=zsh
./install.sh --setup-completion=fish
```
Target paths:
| bash | `${XDG_DATA_HOME:-~/.local/share}/bash-completion/completions/btr` |
| zsh | `${ZDOTDIR:-~}/.zsh/completions/_btr` (you add the dir to `fpath`) |
| fish | `${XDG_CONFIG_HOME:-~/.config}/fish/completions/btr.fish` |
PowerShell and Elvish are not supported by `--setup-completion` because
their install paths are environment-specific; the installer prints the
manual command to run instead.
To dump all scripts into a directory of your choice without writing into
the shell user dirs, use the older flag:
```bash
./install.sh --install-completions /tmp/btr-completions
ls /tmp/btr-completions
# btr.bash btr.elvish btr.fish btr.power-shell btr.zsh
```
## Verification
In a directory with a `.btr.toml`:
```text
btr <TAB><TAB> # built-in subcommands + your custom ones via exec
btr exec <TAB><TAB> # command names from your .btr.toml
btr --profile <TAB> # your profile names (if any)
btr workspace --name <TAB> # discovered workspace project names
btr workspace --tag <TAB> # discovered project tags
btr --workspace <TAB> # directory completion
btr --log-dir <TAB> # directory completion
btr init --template <TAB> # rust node pnpm yarn bun deno nextjs vite turbo nx ...
```
Manual probe of the dynamic helper (the same call the wrappers make):
```bash
btr complete commands
btr complete profiles
btr complete workspace-names
btr complete workspace-tags
btr complete shells
```
Outside a `.btr.toml` tree, the helper returns empty output and exits 0 by design — that keeps TAB silent rather than throwing errors.
## Troubleshooting
| `btr <TAB>` does nothing | bash-completion not sourced | Install `bash-completion` and source it from `~/.bashrc` |
| Subcommands complete, but `btr exec <TAB>` is empty | Old static script, or running from outside a repo | Regenerate with the current `btr`; cd into a dir with `.btr.toml` |
| `btr exec <TAB>` is empty in zsh | `compinit` not run, or fpath order wrong | Add `autoload -U compinit && compinit` to `~/.zshrc`; ensure your fpath dir is before `compinit` |
| `btr exec <TAB>` is empty in PowerShell / elvish | Expected — those shells get static completion only | Use bash/zsh/fish, or invoke `btr complete commands` manually |
| Completion lists stale commands | Shell cached the old function | `exec bash` / `exec zsh` / new fish session |
| Dynamic candidates wrong for current project | `btr` running against a different `.btr.toml` | `btr complete commands` reads from `$PWD` upward — `cd` into the right directory |
Confirm the augmented wrapper is in place:
```bash
grep _btr_dynamic ~/.local/share/bash-completion/completions/btr # bash
grep _btr_dynamic "${fpath[1]}/_btr" # zsh
grep "btr complete" ~/.config/fish/completions/btr.fish # fish
```
Any of those returning matches confirms the dynamic layer is loaded.