A Rust-based plugin manager for fish
Experimental — use at your own risk.
Ensure you have Rust installed on your system. You can install pez using Cargo:
# From crates.io (if available)
cargo install pez
# From source (in this repo)
cargo install --path .
# 1) Initialize configuration (creates pez.toml)
pez init
# 2) Add a plugin to pez.toml (choose one of repo/url/path)
# [[plugins]]
# repo = "owner/repo" # GitHub shorthand
# # version = "v3" # Or: tag = "...", branch = "...", commit = "..."
#
# # [[plugins]]
# # url = "https://gitlab.com/owner/repo" # Any Git host URL
# # branch = "main"
#
# # [[plugins]]
# # path = "~/path/to/local/plugin" # Local directory (absolute or ~/ only)
# # Note: when specifying a relative path at the CLI (e.g., ./plugin), pez normalizes it to an absolute path in pez.toml.
# 3) Install plugins listed in pez.toml
pez install
# 4) Verify installation
pez list --format table
# 5) (Optional) Enable completions for pez itself
pez completions fish > ~/.config/fish/completions/pez.fish
pez completions fish > ~/.config/fish/completions/pez.fish
Usage: pez [OPTIONS] <COMMAND>
Commands:
init | install | uninstall | upgrade | list | prune | completions | doctor | migrate
Options:
-v, --verbose Increase output verbosity (-v for info, -vv for debug)
-h, --help Print help
-V, --version Print version
Common examples
pez init
pez install # install from pez.toml
pez install owner/repo # install a specific plugin
pez upgrade # update non-local plugins to remote HEAD
pez list --outdated --format table
pez prune --dry-run
See the full command reference in docs/commands.md.
pez uses two main configuration files: pez.toml
and pez-lock.toml
.
By default, these files are created in the fish configuration directory,
but you can specify a different location using environment variables.
Configuration file locations
pez looks for pez.toml
and pez-lock.toml
in the following order:
$PEZ_CONFIG_DIR
> $__fish_config_dir
> $XDG_CONFIG_HOME/fish
> ~/.config/fish
.
PEZ_TARGET_DIR
only affects where plugin files are copied. If you previously relied on
PEZ_TARGET_DIR
to relocate your configuration files, move pez.toml
and
pez-lock.toml
into the directory referenced by PEZ_CONFIG_DIR
(or set
PEZ_CONFIG_DIR
to that path) before running newer versions of pez.
pez.toml
is the primary configuration file where you define the plugins
you want to manage. Below is an example structure:
# GitHub shorthand
[[plugins]]
repo = "owner/repo"
# version = "latest" # default if omitted
# version = "v3" # branch or tag name; branches preferred over tags
# branch = "develop"
# tag = "v1.0.0"
# commit = "<sha>" # 7+ chars recommended (unique per repo)
# Generic Git host URL
[[plugins]]
url = "https://gitlab.com/owner/repo"
# branch = "main"
# Local path (absolute or ~/ only)
[[plugins]]
path = "~/path/to/local/plugin"
pez-lock.toml
is automatically generated and maintained by pez.
It records detailed information about the installed plugins,
including their source repositories and specific commit SHAs.
Do not edit this file manually.
pez clones plugin repositories into a designated data directory,
prioritized as follows:
$PEZ_DATA_DIR
> $__fish_user_data_dir/pez
> $XDG_DATA_HOME/fish/pez
> ~/.local/share/fish/pez
When you install a plugin, pez clones its repository into pez_data_dir
.
If the directory doesn’t exist, pez will create it.
Remote repositories that specify a host are stored under <host>/<owner>/<repo>
within that data directory (for example gitlab.com/owner/tool
). GitHub shorthand
targets (owner/repo
) continue to resolve to github.com/owner/repo
.
If the repository is already cloned:
- For explicit CLI targets (
pez install owner/repo ...
), pez logs a warning and skips the reinstall unless you pass--force
. - For installs driven by
pez.toml
(pez install
with no targets), entries that already exist inpez-lock.toml
and on disk are treated as up to date and skipped unless you pass--force
. If a clone exists without a matching lockfile entry, pez returns an error unless you pass--force
.
After cloning, if the repository contains functions, completions, conf.d, or themes directories, pez will recursively copy files from these directories to the corresponding fish configuration directories:
~/.config/fish/functions
~/.config/fish/completions
~/.config/fish/conf.d
~/.config/fish/themes
When installing plugins (either from pez.toml or explicit targets), pez detects duplicate destination paths across all plugins in the same run and skips the conflicting plugin with a warning to avoid overwriting existing files.
The destination fish configuration directory can be overridden using
PEZ_TARGET_DIR
; when it is unset, pez falls back to
$__fish_config_dir
> $XDG_CONFIG_HOME/fish
> ~/.config/fish
.
Additionally, pez-lock.toml
records information about the installed plugins
and the files copied. It is created in the same directory as pez.toml
and is updated if it already exists.
Control job parallelism with the global --jobs <N>
flag or the PEZ_JOBS
environment variable (default: 4). The CLI flag takes precedence over the
environment variable.
install
(when CLI explicit targets are given): cloning is bounded by the configured job limitupgrade
/uninstall
/prune
also honor the same job limit
- CLI explicit targets: skip with a warning unless
--force
(re‑clone). - From
pez.toml
(no targets): entries already tracked inpez-lock.toml
with an existing clone are skipped unless you pass--force
. If a clone exists without a matching lockfile entry, pez returns an error unless you pass--force
.
pez is inspired by the following projects:
MIT
tetzng