// ZSH-PIP-DESCRIPTION-COMPLETION — ENGINEERING REPORT

7 binary aliases (pip/pip2/pip-2.7/pip3/pip-3.2/pip-3.3/pip-3.4) · live pip search for remote PyPI completion · version + description rendered inline in zsh menu · PyPI HTML-index cache (~/.pip/zsh-cache) · zsh-pip-clear-cache autoload

>_EXECUTIVE SUMMARY

zsh-pip-description-completion is a #compdef completion plugin that registers against seven pip-binary aliases (pip, pip2, pip-2.7, pip3, pip-3.2, pip-3.3, pip-3.4) in a single declaration. It ships the full pip 8 subcommand surface (13 subcommands — install, download, uninstall, freeze, list, show, search, wheel, hash, help, plus deprecated bundle/unzip/zip) with hand-curated descriptions, full top-level flag coverage (proxy, retries, timeout, exists-action, cache-dir, trusted-host, cert, client-cert, etc.), and menu-inline version + description rendering — the killer feature. pip install <TAB> shells out to pip search $PREFIX, parses the 4-column output (name version_paren - desc), and feeds zsh's _describe a tag→description map where the description is "$version $desc". The user sees which version is current and what the package does in the completion menu before pressing Enter. A separate PyPI HTML-index cache layer (zsh-pip-cache-packages) curls https://pypi.org/simple/ and stores the parsed package name set in ~/.pip/zsh-cache for offline use. zsh-pip-clear-cache autoload rotates the cache when PyPI's index changes.

144
Total LOC (src + autoload + plugin)
7
Binary Aliases Completed
45
zunit @test Cases
21
Structural Gates (.sh)
6
zunit Files
4
Autoload Helpers

~ARCHITECTURE · FILE STRUCTURE

Three-layer plugin: #compdef consumer under src/, autoload helpers under autoload/ (cache management, name extraction, cache flush), and an entrypoint that wires both into fpath.

Path Lines Role
src/_pip121#compdef pip pip2 pip-2.7 pip3 pip-3.2 pip-3.3 pip-3.4 — 7 binaries, one declaration; 13-entry _1st_arguments subcommand table; top-level flags (--proxy, --timeout, --retries, --cache-dir, etc.); per-subcommand case dispatch for search/install/freeze/uninstall/show
autoload/zsh-pip-cache-packages19Cache builder — curls $ZSH_PIP_INDEXES (default https://pypi.org/simple/), pipes through zsh-pip-clean-packages (sed name extraction from PyPI HTML anchors), sort -u, writes space-separated names to $ZSH_PIP_CACHE_FILE (default ~/.pip/zsh-cache)
autoload/zsh-pip-clean-packages4sed -n '/<a href/ s/.*>\([^<]\{1,\}\).*/\1/p' — one-line PyPI HTML-anchor → package-name extractor
autoload/zsh-pip-clear-cache5Removes $ZSH_PIP_CACHE_FILE and unsets in-shell piplist array
autoload/zsh-pip-test-clean-packages~10Self-test for the sed extractor against a frozen PyPI HTML fixture
zsh-pip-description-completion.plugin.zsh23ZSH_PIP_CACHE_FILE=~/.pip/zsh-cache; ZSH_PIP_INDEXES=(https://pypi.org/simple/); fpath=("${0:h}/src" $fpath); fpath+=("${0:h}/autoload"); autoload -Uz "${0:h}/autoload/"*(.:t)
Total source~1826 files across src/ + autoload/ + entrypoint

@COMPLETION COVERAGE

Full pip surface plus the menu-inline description feature that gives this plugin its name.

7 binary aliases, one #compdef

Zsh's #compdef directive accepts a space-separated list. One declaration #compdef pip pip2 pip-2.7 pip3 pip-3.2 pip-3.3 pip-3.4 registers the same completer against every Python-version-suffixed pip alias users actually have on their PATH (system pip, virtualenv pip, pyenv-shimmed pip, etc.). No need for symlinks.

13 subcommands with descriptions

  • install, download, uninstall, freeze, list, show, search, wheel, hash, help
  • Deprecated (still completable): bundle, unzip, zip — explicitly marked (deprecated) in description so the user knows

Live pip install with version + desc

pip install <TAB>__pip_searchpip search $PREFIX output parsed as name version_paren - desctmp_ary+=("${(q)name}:${(q)version} $desc"). The name:description pair feeds _describe; description renders as (version) description text inline in the menu. This is the feature that gives the plugin its name — you see what the package does before you install it.

Top-level flag surface

  • Help/version: -h/--help, -V/--version
  • Verbosity: -v/--verbose-q/--quiet (mutex)
  • Network: --proxy, --retries, --timeout, --trusted-host
  • Cert: --cert, --client-cert
  • Cache: --cache-dir, --no-cache-dir
  • Misc: --log, --isolated, --exists-action, --disable-pip-version-check
  • Deprecated: -E/--environment, -s/--enable-site-packages

Per-subcommand argument completion

  • install: -U/--upgrade, --user, -f/--find-links, -r/--requirement (_files), --no-deps, -e/--editable (dir-only via _files -/), packages via __pip_search with fallback to *.tar.gz/*.whl file completion
  • freeze: -l/--local
  • search: --index for custom PyPI URL
  • uninstall / show: __pip_installedpip freeze | cut -d '=' -f 1_wanted installed_pkgs

HTML-index cache (offline)

__pip_allzsh-pip-cache-packagescurl https://pypi.org/simple/sed name extraction → sort -u~/.pip/zsh-cache. Cached on first use; cleared with zsh-pip-clear-cache. Means offline tab completion works after one online warm-up.


#TEST COVERAGE

45 zunit @test cases across 6 files, plus 21 structural shell gates from the umbrella.

Test file @test count What it pins
tests/t-plugin.zsh23Plugin-entrypoint surface — ZSH_PIP_CACHE_FILE + ZSH_PIP_INDEXES defaults pinned; fpath contains both src/ and autoload/; all 4 autoload helpers autoloaded via autoload -Uz; _pip file present with multi-binary #compdef line
tests/t-contract.zsh3Entrypoint stem matches plugin-dir basename; #compdef declaration covers all 7 pip aliases
tests/t-contract2.zsh6ZSH_ARGZERO self-locate idiom intact; fpath manipulation order (src/ first, autoload/ appended)
tests/t-contract3.zsh5Helper-function shape — __pip_search uses prefix-keyed cache name pip_${PREFIX}_cache; __pip_installed calls pip freeze | cut -d '=' -f 1; __pip_all guards on $+piplist
tests/t-contract4.zsh5Autoload contract — every autoload/ helper has a self-invoking last line (fn-name "$@"); zsh-pip-clean-packages sed regex matches PyPI HTML anchor format
tests/t-syntax.zsh3zsh -n parse-cleanness on entrypoint, src/_pip, and every autoload/ helper
Total456 zunit files

// STRUCTURAL GATES (21 shell scripts)

Same 21-script umbrella gate-set: 9 docs/*.html gates + 4 README + 3 man-page + 2 tests/ + 2 workflows + 1 cargo (vacuous).


?KEY DESIGN DECISIONS

Five places this plugin diverges from the upstream OMZ pip plugin.

Version + description in the menu

Upstream OMZ pip completion offers bare package names. This plugin parses pip search's 4-column output and feeds _describe a description string of "$version $desc" — so pip install requests<TAB> shows the version and one-line description for every requests* match. Tab completion becomes a low-friction package-discovery surface.

7-binary #compdef in one line

Most plugins register one binary per #compdef, then symlink or duplicate. This plugin uses #compdef pip pip2 pip-2.7 pip3 pip-3.2 pip-3.3 pip-3.4 — zsh accepts the space-separated list natively. Means every Python-version-suffixed pip alias on the user's PATH (system, pyenv, conda, virtualenv) gets the same completion table with zero duplication.

Cache to ~/.pip/zsh-cache, not ~/.zcompcache

The PyPI HTML-index cache lives next to pip's own config (~/.pip/) rather than zsh's cache dir. Rationale: this is a pip-derived artifact, and the user might want to inspect/share/version it. ~/.zcompcache/ is for opaque zsh-internal caches; this plugin's cache is a human-readable space-separated word list.

HTML-index, not JSON API

PyPI offers both an HTML index (/simple/) and a JSON API. This plugin curls the HTML index because it's the canonical, never-deprecated, all-packages-in-one-response surface. The JSON API requires per-package queries. sed -n '/<a href/ s/.*>\([^<]\{1,\}\).*/\1/p' extracts every package name in one pipeline pass.

Separate __pip_search + __pip_all paths

__pip_search is for pip install <prefix> (live search, per-prefix cached). __pip_all is for contexts that need the entire PyPI corpus (autocompleting a bare pip install <TAB> with no prefix yet). Two code paths because the cost profiles differ — __pip_search is a network call per prefix, __pip_all is a one-time HTML-index download.