Skip to content

Add shtab to third-party contrib list - #3793

Open
casperdcl wants to merge 1 commit into
pallets:mainfrom
tqdm:contrib-shtab
Open

Add shtab to third-party contrib list#3793
casperdcl wants to merge 1 commit into
pallets:mainfrom
tqdm:contrib-shtab

Conversation

@casperdcl

@casperdcl casperdcl commented Aug 24, 2026

Copy link
Copy Markdown

Adds shtab to https://click.palletsprojects.com/en/stable/contrib/#third-party-projects (sorted by stars).

shtab.click speeds up click's tab completion (particularly noticeable for complex apps) and adds support for more shells natively (currently bash, zsh, fish, tcsh, pwsh, powershell).

Note

click's _APP_COMPLETE=bash_source app creates a script which calls _APP_COMPLETE=bash_complete app on every TAB press, while shtab.click has the opposite approach - completions a pre-generated by default, and dynamic completions must be explicitly requested via e.g. shtab.cmd.

Existing projects are supported without any source code changes, e.g.:

- example usage
click eval "$(_DOITLIVE_COMPLETE=bash_source doitlive)"
shtab1 eval "$(shtab -u doitlive.cli.cli --prog doitlive)"
click _ZENODO_GET_COMPLETE=zsh_source zenodo_get > _zenodo_get
shtab2 shtab -u zenodo_get.zget.cli --prog zenodo_get -s zsh > _zenodo_get
click _SQLITE_UTILS_COMPLETE=fish_source sqlite-utils | source
shtab3 shtab -u sqlite_utils.cli.cli --prog sqlite-utils -s fish | source

@casperdcl casperdcl mentioned this pull request Aug 24, 2026
3 tasks
@davidism

Copy link
Copy Markdown
Member

Could you explain what this is doing? It seems like it's trying to turn Click into argparse, removing all dynamic behavior and non-argparse-compatible behavior. Click and its shell completions are deliberately very customizable, it's not clear how this is supported. I don't think the basic description "speed up tab completion scripts" is accurate enough to capture the tradeoff.

@casperdcl

casperdcl commented Aug 24, 2026

Copy link
Copy Markdown
Author

Under-the-hood, a click.Command is turned into a temporary argparse object purely as an intermediate step in creating a completion script. Routing via any stdlib (such as argparse) is an implementation detail and unworthy of mention IMO.

Click's completions are currently unusably slow for complex apps, and it's not always desirable to move everything to lazy imports purely to make click's completions faster.

Using shtab.click instead does indeed deliberately remove all side-effects of the completion scripts (though it's likely easy to auto-detect hasattr('shell_complete') to retain dynamic completion support where appropriate, vis. tqdm/shtab#255).

The speedup feels noticeable even with the simple examples in the table above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants