qpath
Quick Path — register, list, and maintain frequently used file and directory paths.
qpath keeps a registry of path abbreviations in TOML files, renders them through a small template language, drops entries whose paths do not exist, and prints the rest for shell and editor integration. It is designed as a data source: shell widgets and editor commands read its output instead of maintaining their own path lists.
Installation
% cargo install qpath --locked
Or from a checkout:
% cargo install --path . --locked
Configuration
Definitions are loaded from, in this order:
~/.config/qpath/paths.toml # default target for editing commands
~/.config/qpath/paths.d/*.toml # sorted by file name
The same abbreviation may be defined more than once; like git config, the last definition in load order wins (among entries that pass type and existence filtering). This lets a later file under paths.d/ override an entry from paths.toml.
Each [[path]] table defines one entry:
[[]]
= "gh"
= "~/src/github.com/"
= "GitHub"
[[]]
= "i"
= "~/.emacs.d/init.el"
= "file"
abbr and path are required. When desc is missing, the path itself is used as the description in output. type is one of directory (dir, d), file (f), or existent (exist, e); when omitted, a path ending in / is a directory and anything else is existent. A leading ~/ or ~user/ is expanded. Entries whose rendered path does not exist, or does not match their type, are silently skipped.
Templates
Paths are rendered with a Jinja2-like template language (MiniJinja). Built-in variables: home, config_home, data_home, cache_home, state_home, os, and arch. The *_home variables are platform aware — on macOS config_home is ~/Library/Application Support, elsewhere ${XDG_CONFIG_HOME:-~/.config}.
Custom variables can be defined in a [vars] table in any definition file:
[]
= "~/.emacs.d/"
[[]]
= "ed"
= "{{ emacs_dir }}"
= "Emacs"
Available filters:
glob— Expand a glob pattern into an array of matching paths. Brace alternations such as{a,b}are expanded first and each alternative is globbed independently; matches are sorted lexically within each alternative and concatenated. A trailing/restricts matches to directories.vsort— Sort an array in version-fragment order, sopython3.9sorts beforepython3.10andv29.9beforev29.10. Pipeglobthrough this to pick the newest versioned match withlast.shell— Run a command withsh -cand return its standard output, trailing newlines stripped like$(...).cache_ttl=SECONDScaches the output per command under~/.cache/qpath/shell/; failures are never cached.- MiniJinja built-ins such as
first,last,sort,reverse, andjoin.
[[]]
= "sp"
= "{{ '/opt/homebrew/lib/python3.[0-9]*/site-packages/' | glob | vsort | last }}"
= "Python site-packages"
[[]]
= "p"
= "{{ '~/{.Debfile,.Brewfile}' | glob | first }}"
= "Package list"
[[]]
= "brew"
= "{{ 'brew --prefix' | shell(cache_ttl=86400) }}/etc/"
= "Homebrew etc"
Usage
Listing
% qpath ls
as ~/Library/Application Support/ /Users/you/Library/Application Support/ ~/Library/Application\ Support/
gh GitHub /Users/you/src/github.com/ ~/src/github.com/
qpath ls [--type TYPE] [--format tsv|json] [--expand] lists entries as abbr, desc, path, shell_path TSV columns or a JSON array. path is the raw absolute path, ready to pass to file APIs. shell_path is quoted for direct insertion into a shell command line, with a leading ~/ left unquoted so it stays expandable. When desc is missing, the ~/-shortened path is shown instead. --type filters by what the path is on disk (default existent), and --expand makes desc and shell_path use absolute paths instead of shortening under ~/. list is an alias for ls.
qpath show <abbr> [--type TYPE] [--format tsv|json] [--expand] prints the single entry whose abbreviation matches exactly, in the same columns as ls, and errors if no such entry exists (or is filtered out by --type).
Editing
% qpath add gh ~/src/github.com/ --desc GitHub
% qpath update gh ~/src/gitlab.com/
% qpath rename gh hub
% qpath rm hub
% qpath format
Editing commands target ~/.config/qpath/paths.toml by default; --file selects another definition file. They preserve comments and formatting, and keep entries sorted (--sort-by abbr|path). qpath add always appends an entry, so the same abbreviation may appear more than once; --overwrite instead replaces the last existing entry in the target file (or appends if there is none), preserving fields not given on the command line. qpath update <abbr> [path] updates the last existing entry in the target file the same way, but errors if the abbreviation is not present there; the path is optional, so it can change only --desc or --type. Both commands only edit the target file, and warn (add) or point at the other file in the error (update) when the same abbreviation also lives elsewhere. qpath format re-sorts a file edited by hand and tidies its whitespace (trailing spaces, repeated blank lines). remove is an alias for rm, and fmt for format.
Cache
% qpath cache clear [shell]
Removes cached data under ~/.cache/qpath/; with shell, only the shell filter's command cache.
zsh integration
Author
Copyright (c) 2026 Akinori Musha.
Licensed under the MIT license. See LICENSE for details.
Visit the GitHub Repository for the latest information.