# Tab completion

Interfaces built with :func:`tyro.cli()` can be tab completed in interactive
shells without any source code modification.

Completion scripts can be generated by passing the
`--tyro-write-completion {bash/zsh/tcsh} PATH` flag to a tyro CLI. This
generates a completion script and writes it to a specified file. To set up tab
completion, the printed script needs to be written somewhere where your shell
will find it.

> **Note:** Tab completion support is experimental and may have edge cases that are
> still being addressed. Please report any issues you encounter.

## Zsh

For zsh, one option is to emulate the pattern used for completions in
[poetry](https://python-poetry.org/docs):

```bash
# Set up zsh autocompletion for 01_functions.py, which is located in
# tyro/examples.

# (1) Make directory for local completions.
mkdir -p ~/.zfunc

# (2) Write completion script. The name here (_01_functions_py) doesn't matter,
# as long as it's prefixed with an underscore.
python 01_functions.py --tyro-write-completion zsh ~/.zfunc/_01_functions_py
```

And if it's not in your `.zshrc` already:

```bash
# (3) Add .zfunc to our function search path, then initialize completions.
# Ideally this should go in your .zshrc!
fpath+=~/.zfunc
autoload -Uz compinit && compinit
```

## Bash

Local completion scripts for bash can be written as described in the
[bash-complete documentation](https://github.com/scop/bash-completion/blob/master/README.md#FAQ).

> **Q.** Where should I install my own local completions?
>
> **A.** Put them in the completions subdir of `$BASH_COMPLETION_USER_DIR`
> (defaults to `$XDG_DATA_HOME/bash-completion` or
> `~/.local/share/bash-completion` if `$XDG_DATA_HOME` is not set) to have them
> loaded automatically on demand when the respective command is being completed
> [...]

Borrowing from the `bash-completion` source[^bash_completion], we can run:

<!-- prettier-ignore-start -->

[^bash_completion]: `completion_dir` query is borrowed from [here](https://github.com/scop/bash-completion/blob/966a4e043822613040546e8c003509798c5fae1a/bash_completion#L2440).

<!-- prettier-ignore-end -->

```bash
# Set up bash autocompletion for 01_functions.py, which is located in
# tyro/examples.

# (1) Find and make completion directory.
completion_dir=${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions/
mkdir -p $completion_dir

# (2) Write completion scripts. The name of the completion script must match
# the name of the file.
python 01_functions.py --tyro-write-completion bash ${completion_dir}/01_functions.py
```

In contrast to zsh, tab completion in bash requires that scripts are either set
up as an entrypoint or run as :code:`./01_functions.py <TAB>`, as opposed to
with the `python` command, :code:`python 01_functions.py <TAB>`.

Making a script directly executable typically requires:

1. A permissions update: `chmod +x ./01_functions.py`.
2. A shebang as the first line of your script: `#!/usr/bin/env python`
