>_EXECUTIVE SUMMARY
zsh-cargo-completion ships every cargo subcommand + flag completion that Oh My Zsh's cargo plugin carries, plus a live cargo search-backed completer for the remote-crate-name positional argument of cargo add and cargo install. Type cargo add ran<TAB> and the completer fires cargo search --color=never --limit 1000 -q ran, parses the response, caches it via zsh's built-in _retrieve_cache / _store_cache memoization layer (so the next TAB against the same prefix is local), and feeds the resulting crate:description pairs to _describe. Total surface: 450 lines in src/_cargo, plus a 23-line plugin entry that adds ${0:h}/src to fpath and exposes 17 cargo aliases. Pinned by 172 @test blocks across 6 zunit files.
~ARCHITECTURE
Two-file shape. The plugin file is alias-only + an fpath nudge; the compdef file is the entire completion engine.
| File | Lines | Role |
|---|---|---|
zsh-cargo-completion.plugin.zsh |
23 | Plugin entry. Declares 17 cargo aliases (co, cr, cb, cbr, ct, ccy, cfm, cfi, cfa, cad, ci, ciu, cs, cfe, cpa, cpl, ccl). Runs the Zsh Plugin Standard 0= header to resolve its own path, then prepends ${0:h}/src to fpath so compinit picks up src/_cargo. |
src/_cargo |
450 | The completion. Starts with #compdef cargo, autoloads regexp-replace, defines __cargo_remote_packages (the live crates.io completer), _cargo (top-level dispatcher), and 8 helper-completion fns (_cargo_unstable_flags, _cargo_installed_crates, _cargo_cmds, _cargo_package_names, _cargo_names_from_array, _cargo_example_names, _cargo_test_names, _cargo_benchmark_names). The big case statement under _cargo dispatches to 33 per-subcommand arms (add, bench, build, check, clean, clippy, config, doc, fetch, fix, fmt, init, install, locate-project, login, logout, metadata, new, owner, package, pkgid, publish, run, rustc, rustdoc, search, test, tree, uninstall, update, vendor, version, yank) — each wrapping an _arguments block with the subcommand's flag table. |
| Total source | 473 | 2 files · pure zsh · compsys-native |
#TEST COVERAGE
172 @test blocks across 6 zunit files under tests/t-*.zsh. Plus 18 portable shell gates under tests/*.sh (final-newline, has-h1, no-deprecated-tags, no-inline-handlers, target-blank-rel-noopener, shell-shebang, workflow-no-tabs, ...) that run alongside the zunit suite.
| File | Tests | Pins |
|---|---|---|
t-aliases.zsh |
21 | Each of the 17 aliases resolves to the documented cargo invocation; fpath augmentation uses ${0:h}/src (plugin-manager portable); _cargo leads with #compdef cargo. |
t-syntax.zsh |
133 | Every *.zsh in the repo root and every file under src/ parses cleanly under zsh -n. Largest test file by count — covers parse safety per-file, not just per-repo. |
t-contract.zsh |
3 | Plugin-contract pins: entrypoint stem matches plugin dir basename, entrypoint parses under zsh -n, every _* completion file leads with #compdef. |
t-contract2.zsh |
5 | OMZ-style install pins: plugins+=(zsh-cargo-completion) path works; fpath is prepended, not replaced. |
t-contract3.zsh |
5 | Zinit-style install pins: zinit load path resolves; no compile-on-load hooks; nocompile ice honored. |
t-contract4.zsh |
5 | Manual source path: standalone source from any CWD honors ${0:h} resolution; no global state leak before sourcing. |
| Total | 172 | 6 zunit files · alias-surface + syntax + install-path-contract |
/INTEGRATION
Zinit (recommended)
zinit ice lucid nocompilezinit load MenkeTechnologies/zsh-cargo-completionnocompile keeps the source path stable so ${0:h}/src resolves to the real on-disk src/ directory (not the compiled .zwc).
Oh My Zsh
Clone into $ZSH_CUSTOM/plugins/zsh-cargo-completion, then add to plugins=(...). OMZ sources zsh-cargo-completion.plugin.zsh, the file declares its aliases, augments fpath, and OMZ's own compinit picks up _cargo on the next prompt.
Cache layer (zsh built-in)
__cargo_remote_packages uses _retrieve_cache + _store_cache keyed by crate_${PREFIX}_cache. First TAB against a prefix fires cargo search; subsequent TABs on the same prefix hit the cache. Cache TTL is governed by zsh's zstyle ':completion::complete:*' use-cache yes — user-tunable.
OMZ plugin compatibility
The 17 aliases overlap intentionally with the OMZ rust / cargo plugins (co, cr, cb, ct, ...) — load order is "OMZ first, then this plugin" so the local aliases win, but the underlying cargo CLI shape is identical.
No daemon, no fork hot path
The only external process invocation is cargo search — gated behind a prefix length check (skipped if $PREFIX starts with -) and gated again behind the cache. Every other completion path (subcommand list via cargo --list, installed crates via cargo install --list, local package names) is also cached.
Public-callable helpers
The 8 helper fns are namespaced (_cargo_*) — user-defined completions and sibling plugins can reuse them. _cargo_installed_crates in particular is the answer to "complete the binary name for cargo uninstall / cargo install --force" — no zsh-cargo-completion-specific knowledge required to call it.
!DESIGN DECISIONS
Live cargo search, not a vendored crate index
A vendored crate index would go stale on day one. The completer shells out to cargo search — the same code path the user would run manually — so the result reflects the current published crates.io state. The cost is one network call per uncached prefix; the gain is a completion that never lies.
2-tier memoization: parameter + on-disk cache
The first cache tier is a zsh parameter (__crate_${PREFIX}) probed via $+param. The second is the standard _retrieve_cache / _store_cache on-disk cache. The parameter tier wins within a single shell session (no ~/.zcompcache stat); the on-disk tier wins across sessions.
Skip remote lookup on flag prefix
[[ "$PREFIX" == -* ]] && return 1 at the top of __cargo_remote_packages — when the user is in the middle of typing a flag (e.g. cargo add --quiet), the completer doesn't fire cargo search. Two seconds saved per accidental TAB on flags.
Subcommand list via cargo --list, not a hardcoded table
_cargo_cmds parses cargo --list output (after dropping the header and de-indenting), then feeds it to _describe. New custom subcommands (anything on $PATH matching cargo-*) appear in completion automatically — no plugin update required.
33 per-subcommand _arguments arms, not a single mega-arm
cargo's flag surface is split per subcommand. The completion mirrors that shape — cargo build flags don't leak into cargo install completions and vice versa. Cost: 450 lines of _cargo file. Gain: each TAB shows only the flags that the subcommand under cursor actually accepts.
Aliases live in the plugin file, not in the README
The 17 aliases ship as live alias commands in zsh-cargo-completion.plugin.zsh — the README is documentation, the plugin file is the source of truth. t-aliases.zsh pins both surfaces stay in sync.
@FOOTPRINT
- Disk:
~/.oh-my-zsh/custom/plugins/zsh-cargo-completion(or zinit cache). Two source files, plus shipped tests. - Memory: zero permanent allocations — the per-prefix
__crate_${PREFIX}caches live for the shell session and clear on exit. - Compinit cost: one extra
fpathentry, one extra_cargofile — folded into the existingcompinitpass, no new compile step. - Network: one
cargo searchper uncached prefix oncargo add/cargo install— bounded to crates.io; opt out by typing without TAB. - External commands:
cargoonly (for--list,search,install --list). Nocurl, nojq, nogit.