How It Works¶
mise-completions-sync follows a simple process to generate shell completions:
- Discover installed tools - Gets list of installed tools via
mise ls --installed --json(or optional flags--global,--local,--current) - Look up registry entries - Each tool is matched against the built-in registry
- Generate completions - Runs the tool's completion command (e.g.,
kubectl completion zsh) - Save output - Writes completions to
~/.local/share/mise-completions/<shell>/
Registry¶
The registry (registry.toml) maps each tool to the command that prints its
completion script. Most tools share a handful of conventions, so those live in
[patterns], where {} stands in for the tool name:
[patterns]
standard = { zsh = "{} completion zsh", bash = "{} completion bash", fish = "{} completion fish" }
[tools]
kubectl = "standard"
A tool whose command doesn't fit a pattern spells it out per shell. Omitting a shell means the tool doesn't support it:
Three optional fields cover tools that need more than a command:
requiresnames another mise tool that must be on PATH while generating, for tools that shell out to a helper.fnoxrenders throughusage:
-
provided_bymarks a binary that arrives as part of another mise tool rather than being one itself, likeuvxfromuv. Its completions are generated whenever the provider is installed. -
bundledmeans the tool has no completion command and ships the files in its download instead. Each shell's value is then the filename to look for:
hyperfine = { bundled = true, zsh = "_hyperfine", bash = "hyperfine.bash", fish = "hyperfine.fish" }
The file is searched for by name beneath mise where <tool>, because the
directory holding it encodes the version and platform
(hyperfine-v1.20.0-x86_64-apple-darwin/autocomplete) and cannot be written
down in advance. The shallowest match wins.
Commands run inside mise x <tool> -- …, so they resolve against the version
mise has installed rather than whatever is on your PATH. A bundled entry runs
nothing — its file is copied straight out of the install directory.
Custom Registry¶
The built-in registry is embedded in the binary, but you can extend it. If a
registry.toml exists next to the executable, or at
${XDG_DATA_HOME:-$HOME/.local/share}/mise-completions-sync/registry.toml, it is laid on top of
the built-in one rather than replacing it.
schema_version = 1
[tools]
# a tool the built-in registry doesn't know about
graphite-cli = { zsh = "gt completion zsh", bash = "gt completion bash" }
# built-in patterns are available to your entries
mytool = "standard"
# and you can override a built-in entry
yq = { zsh = "yq shell-completion zsh" }
# or switch one off, e.g. when another source already completes the tool
usage = false
Merging happens before patterns are resolved, so your entries can use the
built-in patterns, and redefining a pattern reaches every tool that references
it. schema_version is required.
An entry set to false is skipped by sync, and misecompsync clean removes the
files it wrote earlier, even while the tool stays installed. Only false is
accepted; true is an error, since there is nothing for it to switch on.
Switching off a tool doesn't switch off its companions: uv = false leaves
uvx syncing while uv is installed.
The executable's directory takes precedence over the XDG location, and only one user registry applies.
Output Locations¶
By default, completions are saved to $XDG_DATA_HOME/mise-completions/<shell>.
Each tool gets its own completion file named _<tool> (for zsh) or <tool>.bash/<tool>.fish for other shells.
You can override the default output directory using the MISE_COMPLETIONS_SYNC_HOME environment variable:
export MISE_COMPLETIONS_SYNC_HOME="$XDG_DATA_HOME/custom-vendor-completions"
misecompsync kubectl
# [fish] -> ~/.local/share/custom-vendor-completions/fish/kubectl.fish
# [zsh] -> ~/.local/share/custom-vendor-completions/zsh/_kubectl
# [bash] -> ~/.local/share/custom-vendor-completions/bash/kubectl
Or you can override output directories for one (or more) shells (e.g., MISE_COMPLETIONS_SYNC_{SHELL}_DIR)
export MISE_COMPLETIONS_SYNC_FISH_DIR="$XDG_CONFIG_HOME/fish/completions"
misecompsync kubectl
# [fish] -> ~/.config/fish/completions/kubectl.fish
# [zsh] -> ~/.local/share/mise-completions/zsh/_kubectl
# [bash] -> ~/.local/share/mise-completions/bash/kubectl
Or a shell dir with base dir default (shell takes precedence):
export MISE_COMPLETIONS_SYNC_HOME="$XDG_DATA_HOME/custom-vendor-completions"
export MISE_COMPLETIONS_SYNC_ZSH_DIR="$XDG_DATA_HOME/zsh/site-functions"
misecompsync kubectl
# [fish] -> ~/.local/share/custom-vendor-completions/fish/kubectl.fish
# [zsh] -> ~/.local/share/zsh/site-functions/_kubectl
# [bash] -> ~/.local/share/custom-vendor-completions/bash/kubectl
Note: Target directories will be created if they don't already exist.