From ab84cca50a60b905474c2da4251a1d91be866317 Mon Sep 17 00:00:00 2001 From: Matheus Felipe Date: Wed, 5 Aug 2026 13:21:07 -0300 Subject: [PATCH] feat(pipenv): add completion for >= 2026.5.0 (#13686) Co-authored-by: Carlo Sala --- plugins/pipenv/README.md | 14 ++++++++- plugins/pipenv/pipenv.plugin.zsh | 49 +++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/plugins/pipenv/README.md b/plugins/pipenv/README.md index 429b6f186..544d07997 100644 --- a/plugins/pipenv/README.md +++ b/plugins/pipenv/README.md @@ -10,7 +10,7 @@ plugins=(... pipenv ...) ## Features -- Adds completion for pipenv +- Adds completion for pipenv ([install the `argcomplete` package to get it working with pipenv >= 2026.5.0](https://pipenv.pypa.io/en/latest/shell.html#shell-completion)) - Auto activates and deactivates pipenv shell - Adds short aliases for common pipenv commands - `pch` is aliased to `pipenv check` @@ -29,6 +29,18 @@ plugins=(... pipenv ...) - `pvenv` is aliased to `pipenv --venv` - `ppy` is aliased to `pipenv --py` +## Cache + +This plugin caches the Pipenv version to avoid running `pipenv --version` on every shell startup. The cache is automatically refreshed asynchronously when the plugin is loaded, which is usually when you start a new terminal session. + +For legacy Pipenv versions, the generated completion script is also cached. + +The cache is stored at: + +- `$ZSH_CACHE_DIR/pipenv_version` version of Pipenv, used to choose between argcomplete-based completion and legacy Click-based completion. + +- `$ZSH_CACHE_DIR/completions/_pipenv` legacy Click-based completion script. + ## Configuration ### Shell activation diff --git a/plugins/pipenv/pipenv.plugin.zsh b/plugins/pipenv/pipenv.plugin.zsh index 76d66b301..802641a0e 100644 --- a/plugins/pipenv/pipenv.plugin.zsh +++ b/plugins/pipenv/pipenv.plugin.zsh @@ -2,15 +2,49 @@ if (( ! $+commands[pipenv] )); then return fi -# If the completion file doesn't exist yet, we need to autoload it and -# bind it to `pipenv`. Otherwise, compinit will have already done that. -if [[ ! -f "$ZSH_CACHE_DIR/completions/_pipenv" ]]; then - typeset -g -A _comps - autoload -Uz _pipenv - _comps[pipenv]=_pipenv +# Compatibility note: +# pipenv < 2026.5.0 used Click-based shell completion driven by the +# _PIPENV_COMPLETE environment variable. +# +# pipenv >= 2026.5.0 removed this mechanism and switched to argcomplete-based +# completion using register-python-argcomplete instead. + +autoload -Uz is-at-least + +_pipenv_version_cache="$ZSH_CACHE_DIR/pipenv_version" + +if [[ -f "$_pipenv_version_cache" ]]; then + _pipenv_version="$(< "$_pipenv_version_cache" 2>/dev/null)" +else + _pipenv_version="${$(pipenv --version 2>/dev/null)#pipenv, version }" fi -_PIPENV_COMPLETE=zsh_source pipenv >| "$ZSH_CACHE_DIR/completions/_pipenv" &| +{ + _pipenv_fresh_version="${$(pipenv --version 2>/dev/null)#pipenv, version }" + [[ -n "$_pipenv_fresh_version" ]] && print -r -- "$_pipenv_fresh_version" >| "$_pipenv_version_cache" +} &| + +if is-at-least 2026.5.0 "$_pipenv_version"; then + # pipenv >= 2026.5.0: argcomplete-based completion (no legacy fallback) + if (( $+commands[register-python-argcomplete] )); then + autoload -Uz bashcompinit + bashcompinit + + eval "$(register-python-argcomplete pipenv)" + fi +else + # legacy Click-based completion via _PIPENV_COMPLETE + + # If the completion file doesn't exist yet, we need to autoload it and + # bind it to `pipenv`. Otherwise, compinit will have already done that. + if [[ ! -f "$ZSH_CACHE_DIR/completions/_pipenv" ]]; then + typeset -g -A _comps + autoload -Uz _pipenv + _comps[pipenv]=_pipenv + fi + + _PIPENV_COMPLETE=zsh_source pipenv >| "$ZSH_CACHE_DIR/completions/_pipenv" &| +fi if zstyle -T ':omz:plugins:pipenv' auto-shell; then # Automatic pipenv shell activation/deactivation @@ -34,6 +68,7 @@ if zstyle -T ':omz:plugins:pipenv' auto-shell; then fi fi } + autoload -U add-zsh-hook add-zsh-hook chpwd _togglePipenvShell _togglePipenvShell