Fast tab completion, plus ready-made command snippets on @<TAB>, for the bash that ships
with macOS (/bin/bash 3.2), any newer bash, and zsh. One small C binary, no shell scripts, no dependencies.
It does two things:
- Tab completion for the commands you type every day: subcommands, flags with descriptions, and live values such as git branches, docker networks and make targets.
- Snippets: type a command, then
@<TAB>, and pick a complete, working command line. No more looking up the curl flags for posting JSON or how to make a tarball.
$ git checkout fe<TAB>
$ git checkout feature/login
$ docker run --network <TAB>
bridge host none my_app_default
$ tar @<TAB>
📌 @c -- tar -czf backup.tar.gz project/ 📚 create a gzip archive of a folder
📌 @x -- tar -xzf backup.tar.gz 📚 extract a gzip archive here
📌 @t -- tar -tzf backup.tar.gz 📚 list the contents without extracting
🔥 @d -- tar -xzf backup.tar.gz -C /tmp/out 📚 extract into another directory
🔥 @j -- tar -cJf backup.tar.xz project/ 📚 create an xz archive
...
$ tar @x<TAB>
$ tar -xzf backup.tar.gzYou don't need Homebrew bash or the bash-completion package. Pressing TAB runs no
shell code, and new terminals open as fast as before. zsh works too, with the same specs
(zsh).
macOS (Apple silicon, Intel) and Linux (x86_64, arm64). Works with bash 3.2 or newer, and
zsh. No sudo: installs to ~/.local and adds eval "$(autocomplete bash)" to ~/.bashrc
(and eval "$(autocomplete zsh)" to ~/.zshrc when you use zsh).
curl -fsSL https://github.com/hza/autocomplete/releases/latest/download/install.sh | shor with wget:
wget -qO- https://github.com/hza/autocomplete/releases/latest/download/install.sh | shOpen a new terminal and press TAB after git, docker or make. For manual download,
building from source, install options and uninstalling, see
Installation options.
Most completion tools help you spell a flag you already know. Snippets help when you don't
remember which flags you need. Type @ right after the command and press TAB: each snippet
is a working command with a short key and a one-line explanation. @key<TAB> inserts it,
ready to edit. 📌 marks the most used ones, which are listed first. A plain TAB never shows
snippets, so it keeps completing files, hosts and flags as usual.
About 135 commands have snippets. Highlights:
- port (MacPorts): selfupdate, upgrade outdated, leaves, reclaim, reverse dependencies
- curl, wget: POST JSON or form data, uploads, headers only, redirects, resuming
- ps, lsof: top CPU/memory processes, who listens on a port, open files of a process
- find, grep: recently changed files, large files, recursive search with excludes
- tar, zip, unzip, unrar, gzip, xz, bzip2: create, extract, list,
exclude folders, zip without macOS junk, passwords, split archives,
.appbundles - ssh: port forwarding, jump hosts, SOCKS proxy, remote commands
- jq: pretty-print, pick and filter fields, CSV, shell variables
- brew: dependency trees, reverse dependencies, leaves, cleanup, Brewfile backup
- docker:
run,exec, theprunecommands,compose config - kubectl, rsync, ffmpeg, openssl, jfr and many more
- macOS tools: defaults (hidden Finder, Dock and screenshot settings), sips (resize, convert HEIC), mdfind, pbcopy, say, duti
- Shell keywords for, while, until, case, if: practical one-liners
(
if git <TAB>still completes git)
Add your own with a snippets: list in any spec (format).
bash-completion, zsh and fish complete flags and values only. Cheat-sheet tools like navi or tldr show examples, but in a separate command, not at the prompt you're already typing on.
Bundled commands (about 150):
- Version control and build: git, gh, make, mvn, gradle, cargo, go, swift, pod, fastlane
- Languages and packages: python, pip, pyenv, node, npm, npx, yarn, pnpm, bun, bunx, java, jfr, rbenv, asdf, nvm
- Containers and cloud: docker, colima, orbctl, kubectl, kubectx, kubens, k9s, helm, minikube, kind, terraform, pulumi, ansible, aws, az, gcloud, doctl, flyctl, vercel
- Databases: psql, pg_dump, mysql, mysqldump, redis-cli, sqlite3
- Network: ssh, scp, curl, wget, rsync, openssl, dig, nc, tcpdump
- Files and text: find, grep, rg, sed, awk, diff, patch, jq, bat, fzf, tar, zip, unzip, unrar, gzip, xz, bzip2, compress (and their decompressors)
- Processes: ps, kill, pkill, killall, lsof, tmux
- macOS: port (MacPorts), brew, mas, open, defaults, launchctl, diskutil, pmset, networksetup, security, codesign, xcrun, plutil, hdiutil, spctl, xattr, softwareupdate, tccutil, scutil, mdutil, mdfind, mdls, osascript, shortcuts, dscl, log, system_profiler, ditto, textutil, sips, screencapture, say, afplay, qlmanage, caffeinate, pbcopy, pbpaste, duti, profiles, sw_vers, nettop, fs_usage
- Other: code (VS Code), claude (Claude Code), ffmpeg, pngquant, jpegtran, man, help, and
autocompleteitself
Live values from your environment, for example:
- git: branches, tags, remotes, stashes, changed files, your aliases
- docker: containers, images, networks, volumes
- kubectl: namespaces, contexts, pods, nodes, resource types
- make: targets and variables, with descriptions from
## textor the comment above each target (honors-C dirand-f file) - npm, yarn, pnpm, bun, node:
package.jsonscripts and dependencies; npx, bunx: binaries innode_modules/.bin - mvn: profiles, modules and plugin goals from
pom.xml - ssh, scp: hosts from
~/.ssh/configandknown_hosts(scp gr<TAB>→grafana:) - java: source files that declare
main(java <TAB>); python: modules for-m(python3 -m http<TAB>→http.server) - aws, az, gcloud: profiles, subscriptions, projects, regions, buckets
- gh: pull requests, issues, workflow runs, releases; helm: releases and charts; terraform: resources from state
- kill, killall, pkill: running processes; say: voices; open: app names and bundle ids
- duti: file extensions, app bundle ids (also by app name:
duti -s Preview<TAB>) and every UTI known to the system, read live from LaunchServices
More:
- Descriptions next to subcommands and flags (
git stash <TAB>→pop -- Apply a stash and remove it). - Commands with hundreds of flags, like curl and wget, are grouped to fit your screen.
sudo,env,timeandxargscomplete the command after them (sudo git chec<TAB>→checkout).- Handles
--flag=value,image:tag, quoted words and file names with spaces. - Shell aliases complete like the command they wrap (
autocomplete alias kubectl k). - Any other command: generate a spec from its man page or
--helpoutput, or hand Go/cobra programs over to their own completion (details). Withautocomplete bash --scan-man, every command with a man page completes its flags automatically. - Your own commands: write a small YAML file, no rebuild (how).
| Command | Description |
|---|---|
autocomplete bash [--scan-man] |
Print the init script (use with eval). --scan-man also registers every command in $PATH that has a man page and no spec; its flags are read from the man page on first TAB and cached. |
autocomplete zsh [--scan-man] |
Same for zsh: defines one completion function and registers it with compdef (loads compinit if needed). |
autocomplete list [--user] [--paths] [--tsv] |
List commands that have a spec, with descriptions. --user: only your specs in ~/.config/autocomplete. --paths: show which spec file is used. --tsv: NAME<TAB>DESCRIPTION for scripts. Your specs are tagged [override], [added] or [alias -> CMD], plus generated: … and update: NEW > OLD when the shipped spec is newer. |
autocomplete specs |
Same as list --user. |
autocomplete add [--force] [--from cobra|man|help] CMD... |
Write ~/.config/autocomplete/CMD.yaml from the first source that works: cobra, man page, CMD --help. |
autocomplete edit NAME |
Edit your copy of a spec in $VISUAL/$EDITOR/vi, copying the shipped one first if needed. Validates after saving; an unchanged copy is removed. |
autocomplete diff [NAME...] |
diff -u of your copies against the shipped specs. Exits 1 if any differ. |
autocomplete rm [-f] NAME... |
Delete your spec or alias (asks first unless -f); the shipped spec is used again. |
autocomplete alias [--force] CMD NAME... |
Complete NAME like CMD. |
autocomplete alias --rm NAME... / --list |
Remove or list aliases. |
autocomplete check FILE |
Validate a spec and print how it was parsed (as JSON). |
macOS still ships bash 3.2 from 2007, and the usual tools have moved on:
- bash-completion 2.x requires bash 4.2 or newer.
- bash-completion 1.3, the last version for bash 3.2, is unmaintained and loads every completion script at startup, so each new terminal opens slowly.
- The common workaround is
brew install bashand changing your login shell.
autocomplete is built for the bash you already have. It's tested against Apple's /bin/bash
and builds with the Xcode Command Line Tools.
bash-completion is written in bash and sources its scripts into every shell. autocomplete
registers its binary with complete -C, so each TAB runs compiled C directly: no bash
functions, sed/awk pipelines or subshells. Shell startup does only the registration;
specs are read when you press TAB.
- Nothing extra to install. C builds with the Xcode Command Line Tools that most Macs
already have. Rust needs
rustupand a toolchain of about 1 GB just to runmake. - Size. The whole engine, including its own YAML parser, is a ~95 KB binary with no dependencies. A Rust "Hello, world!" release build is already ~300 KB, because Rust's standard library is built into every program.
- Startup time. The binary starts on every TAB, so a small binary that only uses libc keeps each completion fast.
No. Homebrew has dropped support for Intel Macs, so I don't support it. Use the install script above or one of the other options.
Yes. Write ~/.config/autocomplete/<command>.yaml describing its subcommands, flags and
values. See Adding your own commands.
- Installation options: install script options, manual download, building from source, uninstalling
- Adding your own commands: quick start
- Writing specs: spec format, value types, supported YAML, lookup order
- Generating specs:
autocomplete add - Cache: man page specs,
execoutput and other cached results - Troubleshooting: common problems and fixes
- How it works: what happens when you press TAB
MIT. See LICENSE.
