Automatically generate shell tab completion scripts for python CLI apps
Project description
What: Automatically generate shell tab completion scripts for python CLI apps
Why: Speed & correctness. Alternatives like argcomplete & pyzshcomplete are slow and have side-effects
How: shtab processes an argparse.ArgumentParser object to generate a tab completion script for your shell
Features
Outputs completion for bash and zsh
Supports argparse and docopt (via argopt)
Supports arguments, options and subparsers
Supports path completion
Usage
Installing shtab’s own tab completion scripts is possible via:
# Install locally (eager)
echo 'eval "$(shtab --shell=bash shtab.main.get_main_parser)"' \
>> ~/.bash_completion
# Install locally (lazy load for bash-completion>=2.8)
echo 'eval "$(shtab --shell=bash shtab.main.get_main_parser)"' \
> "${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions/shtab"
# Install system-wide
echo 'eval "$(shtab --shell=bash shtab.main.get_main_parser)"' \
| sudo tee "$(pkg-config --variable=completionsdir bash-completion)"/shtab
# Install system-wide (legacy)
echo 'eval "$(shtab --shell=bash shtab.main.get_main_parser)"' \
| sudo tee "$BASH_COMPLETION_COMPAT_DIR"/shtab
# Install once (will have to re-run if the target's CLI API changes,
# but doesn't need target to always be in $PYTHONPATH)
shtab --shell=bash shtab.main.get_main_parser --error-unimportable \
| sudo tee "$BASH_COMPLETION_COMPAT_DIR"/shtab
# zsh equivalent (alternatively place in $fpath/_shtab)
shtab --shell=zsh shtab.main.get_main_parser --error-unimportable \
| sudo tee /usr/local/share/zsh/site-functions/_shtab
The same would work for most existing argparse-based scripts. For example, starting with this existing code:
import argparse
def get_main_parser():
parser = argparse.ArgumentParser(prog="<MY_PROG>", ...)
parser.add_argument(...)
parser.add_subparsers(...)
...
return parser
if __name__ == "__main__":
parser = get_main_parser()
args = parser.parse_args()
...
Assuming this code example is installed in MY_PROG.command.main, simply run:
# bash
echo 'eval "$(shtab --shell=bash MY_PROG.command.main.get_main_parser)"' \
>> ~/.bash_completion
# zsh
shtab --shell=zsh -u MY_PROG.command.main.get_main_parser \
| sudo tee /usr/local/share/zsh/site-functions/_MY_PROG
Configuration
Alternatively, add direct support to scripts for a little more configurability:
import argparse
import shtab, os # for completion magic
def get_main_parser():
parser = argparse.ArgumentParser(prog="<MY_PROG>", ...)
parser.add_argument("--install-completion-shell", choices=["bash", "zsh"])
parser.add_argument(
"--file",
choices=shtab.Optional.FILE, # file tab completion
)
parser.add_argument(
"--dir",
choices=shtab.Required.DIRECTORY, # directory tab completion
default=os.getenv("BASH_COMPLETION_USER_DIR"),
)
...
return parser
if __name__ == "__main__":
parser = get_main_parser()
args = parser.parse_args()
# completion magic
shell = args.install_completion_shell
if shell:
completion_script = shtab.complete(parser, shell=shell)
filename = args.file or "<MY_PROG>"
print("Writing to system completion directory...")
with open(os.path.join(args.dir, filename), "w") as fd:
fd.write(completion_script)
print("Please restart your terminal.")
...
More Examples
#!/usr/bin/env python
"""Greetings and partings.
Usage:
greeter [options] [<you>] [<me>]
Options:
-b, --bye : Say "goodbye" (instead of "hello")
-c, --print-bash-completion : Output a tab-completion script
Arguments:
<you> : Your name [default: Anon]
<me> : My name [default: Casper]
"""
import sys, argopt, shtab
parser = argopt.argopt(__doc__)
if __name__ == "__main__":
args = parser.parse_args()
if args.print_bash_completion:
print(shtab.complete(parser, shell="bash"))
sys.exit(0)
msg = "k thx bai!" if args.bye else "hai!"
print("{} says '{}' to {}".format(args.me, msg, args.you))
Alternatives
argcomplete
executes the underlying script every time <TAB> is pressed (slow and has side-effects)
only provides bash completion
pyzshcomplete
executes the underlying script every time <TAB> is pressed (slow and has side-effects)
only provides zsh completion
click
different framework completely replacing argparse
solves multiple problems (rather than POSIX-style “do one thing well”)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file shtab-0.0.4.tar.gz
.
File metadata
- Download URL: shtab-0.0.4.tar.gz
- Upload date:
- Size: 12.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.1 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.7.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4a46542c7ad87d3b3852956c7bc481cbf9fbd5c1dc6b539065bb28f7afd0a829 |
|
MD5 | b373b9c389f7098617dc3affa6a849e0 |
|
BLAKE2b-256 | 32598b51324cc77eacf8e8ab5ed23082c582d3ef7d4f2232134751526cfb338e |
Provenance
File details
Details for the file shtab-0.0.4-py2.py3-none-any.whl
.
File metadata
- Download URL: shtab-0.0.4-py2.py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.1 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.7.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 56453fcf92326549a9af380991fbbda2520d93d990532f1a022cc6d8b3437edd |
|
MD5 | 161b8996b9f500e63fe9db5ad107638d |
|
BLAKE2b-256 | 030d5d481b462f66f5fb54d7fb1041faa8092467433d5c5b52c9aefabb553609 |