#compdef pip # {{{ common options local common_options_help=( '(- :)'{-h,--help}'[show help]' ) local common_options_pre=( '--pre[Include pre-release and development versions]' ) local common_options_install=( {\*-c,\*--constraint}'[Constrain versions using the given constraints file]:FILE:_files' '(- :)'{-e,--editable}'[Install a project in editable mode (i.e. setuptools "develop mode") from a local project path or a VCS url]:PACKAGE:{__pip_package "url" "file"}' {\*-r,\*--requirement}'[Install from the given requirements file]:FILE:_files' {-b,--build}'[Directory to unpack packages into and build in]:DIRECTORY:_files -/' "--no-deps[Don't install package dependencies]" "${common_options_pre[@]}" '*--global-option=[Extra global options to be supplied to the setup.py call before the install command]:OPTION:_setup.py' '*--no-binary[Do not use binary packages]:FORMAT_CONTROL:__pip_no_binary_control' '*--only-binary[Do not use binary packages]:FORMAT_CONTROL:__pip_only_binary_control' "--no-clean[Don't clean up build directories]" '--require-hashes[Require a hash to check each requirement against, for repeatable installs]' ) local common_options_wheel=( "${common_options_install[@]}" '--src[Directory to check out editable projects into]:DIRECTORY:_files -/' '--ignore-requires-python[Ignore the Requires-Python information]' ) local common_options_index=( '(--no-index)'{-i,--index-url}'[Base URL of Python Package Index (default https://pypi.python.org/simple)]:URL:_urls' '(--no-index)*--extra-index-url[Extra URLs of package indexes to use in addition to --index-url]:URL:_urls' '(-i --index-url)--no-index[Ignore package index (only looking at --find-links URLs instead)]' {-f,--find-links}'[If a url or path to an html file, then parse for links to archives]:URL:__pip_find_links' '--process-dependency-links[Enable the processing of dependency links]' ) local common_options_user=( '--user\[Only output packages installed in user-site\]' ) local common_options_local=( {-l,--local}'[If in a virtualenv that has global access, do not output globally-installed packages]' ) # }}} # {{{ helper: installed packages cache policy __pip_install_packages_cache_policy(){ # TODO: workout a way that will let users configure via zstyle locations of site-packages # the number of seconds since 1970-01-01 the site-packages directories were changed local site_packages_user_dir_last_date_modified="$(date -r ~/.local/lib/python3.6/site-packages +%s 2>/dev/null)" local site_packages_system_dir_last_date_modified="$(date -r /usr/lib/python3.6/site-packages +%s 2>/dev/null)" # the number of seconds since 1970-01-01 the cache file was modified local cache_last_date_modified="$(date -r $1 +%s 2>/dev/null)" if [[ ! -z "${cache_last_date_modified}" ]] && [[ ! -z "${site_packages_user_dir_last_date_modified}" || ! -z "${site_packages_system_dir_last_date_modified}" ]]; then # if the manifest file is newer then the cache: if [[ ${site_packages_user_dir_last_date_modified} -ge ${cache_last_date_modified} ]] || [[ ${site_packages_system_dir_last_date_modified} -ge ${cache_last_date_modified} ]]; then (( 1 )) else (( 0 )) fi else (( 1 )) fi } # }}} # {{{ helper: installed packages (using cache) __pip_installed() { local update_policy zstyle -s ":completion:${curcontext}:" cache-policy update_policy if [[ -z "$update_policy" ]]; then zstyle ":completion:${curcontext}:" cache-policy __pip_install_packages_cache_policy fi if _cache_invalid pip_installed_packages; then installed_packages=($(pip list --format freeze | sed -n -e 's/\([-a-z_]\+\)==.*/\1/p')) _store_cache pip_installed_packages installed_packages else _retrieve_cache pip_installed_packages fi _values "installed packages" "${installed_packages[@]}" } # }}} # {{{ helper: available commands local commands=( 'install:install packages' 'download:download packages' 'uninstall:uninstall packages' 'freeze:output all currently installed packages (exact versions) to stdout' 'list:list installed packages' 'show:show information about installed packages' 'search:search PyPI' 'wheel:build individual wheel archives for your requirements and dependencies' 'hash:compute a hash of a local package archive' 'help:show available commands' ) __pip_commands(){ _describe "pip command" commands } # }}} # {{{ helper: installable packages wrapper __pip_package(){ local -a alts for arg in "$@"; do case $arg in "url") alts+=(':URL of package:_urls') ;; "file") alts+=(':package repo or archive:_files') ;; esac done _alternative "${alts[@]}" } # }}} # {{{ helper: upgrade strategy __pip_upgrade_strategy(){ local strategies=( "eager:dependencies are upgraded whether currently installed version satisfies the requirements or not" "only-if-needed:are upgraded only when they do not satisfy the requirements of the upgraded package(s)" ) _describe "strategy" strategies } # }}} # {{{ helper: binary control __pip_no_binary_control(){ local options=( 'all:"disable all binary packages"' 'none:"enable all binary packages"' ) _alternative ": :((${options[@]}))" ": :_message 'packages to install or use:'" } __pip_only_binary_control(){ local options=( 'all:"enable all binary packages"' 'none:"disable all binary packages"' ) _alternative ": :((${options[@]}))" ": :{_message 'packages to install or use:'}" } # }}} # {{{ helper: look for html file or url with links to packages or find packages in a directory __pip_find_links(){ _alternative ': :_urls' ': :_files -g ".html"' ': :_files -/' } # }}} # {{{ helper: urls or files to install __pip_install_packages(){ _alternative ': :_urls' ': :_files' } # }}} # {{{ command install local command_install_options=( "${common_options_help[@]}" "${common_options_wheel[@]}" "${common_options_index[@]}" {-t,--target}'[Install packages into DIRECTORY]:DIRECTORY:_files -/' {-d,--download}"[Download packages into instead of installing them, regardless of what's already installed]:DIRECTORY:_files -/" {-U,--upgrade}'[Upgrade all specified packages to the newest available version]' '--upgrade-strategy[Determines how dependency upgrading should be handled]:STRATEGY:__pip_upgrade_strategy' '--force-reinstall[When upgrading, reinstall all packages even if they are already up-to-date]' {-I,--ignore-installed}'[Ignore the installed packages (reinstalling instead)]' # TODO: autoload _setup.py to complete options for it '*--install-option=[Extra arguments to be supplied to the setup.py install command]:OPTION:_setup.py' '--user[Install to the Python user install directory for your platform]' "--egg[Install packages as eggs, not 'flat', like pip normally does]" '--root[Install everything relative to this alternate root directory]:DIRECTORY:_files -/' '--prefix[Installation prefix where lib, bin and other top-level folders are place]:DIRECTORY:_files -/' '--compile[Compile py files to pyc]' '--no-compile[Do not compile py files to pyc]' '--no-use-wheel[DEPRECATED in favour of --no-binary]' ) _pip_install(){ _arguments \ "${command_install_options[@]}" \ '*:PACKAGE:__pip_install_packages' } # }}} # {{{ command download local command_download_options=( "${common_options_help[@]}" "${common_options_install[@]}" "${common_options_index[@]}" '--src[Directory to check out editable projects into]:DIRECTORY:_files -/' {-d,--dest}'[Download packages into DIRECTORY]:DIRECTORY:_files -/' '--platform[Only download wheels compatible with PLATFORM]:PLATFORM:' '--python-version[Only download wheels compatible with Python interpreter version VERSION]:VERSION:' '--implementation[Only download wheels compatible with Python implementation IMPLEMENTATION]:IMPLEMENTATION:' '--abi[Only download wheels compatible with Python abi ABI]:ABI:' ) _pip_download(){ _arguments \ "${command_download_options[@]}" \ '*:PACKAGE:__pip_install_packages' } # }}} # {{{ command uninstall local command_uninstall_options=( "${common_options_help[@]}" {\*-r,\*--requirement}'[Uninstall all the packages listed in the given requirements file]:FILE:_files' {-y,--yes}"[Don't ask for confirmation of uninstall deletions]" ) _pip_uninstall(){ _arguments \ "${command_uninstall_options[@]}" \ '*: :__pip_installed' } # }}} # {{{ command freeze local command_freeze_options=( "${common_options_help[@]}" "${common_options_local[@]}" "${common_options_user[@]}" {\*-r,\*--requirement}'[Use the order in the given requirements file and its comments when generating output]:FILE:_files' {-f,--find-links}'[URL for finding packages, which will be added to the output]:URL:_urls' '--all[Do not skip these packages in the output: pip, setuptools, distribute, wheel]' ) _pip_freeze(){ _arguments \ "${command_freeze_options[@]}" } # }}} # {{{ command list local command_list_options=( "${common_options_help[@]}" "${common_options_local[@]}" "${common_options_user[@]}" "${common_options_pre[@]}" {-o,--outdated}'[List outdated packages]' {-u,--uptodate}'[List uptodate packages]' {-e,--editable}'[List editable projects]' '--format[Select the output format among]:FORMAT:(legacy columns freeze json)' '--not-required[List packages that are not dependencies of installed packages]' "${common_options_index[@]}" ) _pip_list(){ _arguments \ "${command_list_options[@]}" \ '1: :' } # }}} # {{{ command show local command_show_options=( "${common_options_help[@]}" {-f,--files}'[Show the full list of installed files for each package]' ) _pip_show(){ _arguments \ "${command_show_options[@]}" \ '*: :__pip_installed' } # }}} # {{{ command search local command_search_options=( "${common_options_help[@]}" {-i,--index}'[Base URL of Python Package Index (default https://pypi.python.org/pypi)]:URL:_urls' ) _pip_search(){ _arguments \ "${command_search_options[@]}" \ '*:QUERY:' } # }}} # {{{ command wheel local command_wheel_options=( "${common_options_help[@]}" "${common_options_wheel[@]}" "${common_options_index[@]}" '(--no-wheel-dir)'{-w,--wheel-dir}'[Build wheels into DIRECTORY (default is current working directory)]:DIRECTORY:_files -/' '(-w --wheel-dir)--no-wheel-dir[Do not Find and prefer wheel archives when searching indexes and find-links locations]' ) _pip_wheel(){ _arguments \ "${command_wheel_options[@]}" \ '*:PACKAGE:__pip_install_packages' } # }}} # {{{ command hash local command_hash_options=( "${common_options_help[@]}" {-a,--algorithm}'[The hash algorithm to use]:ALGORITHM:(sha256 sha384 sha512)' ) _pip_hash(){ _arguments \ "${command_hash_options[@]}" \ '1:PACKAGE_ARCHIVE:_files' } # }}} # {{{ command help local command_help_options=( "${common_options_help[@]}" ) _pip_help(){ _arguments \ "${command_help_options[@]}" \ '1:COMMAND:__pip_commands' } # }}} # The real thing _arguments \ "${common_options_help[@]}" \ '--isolated[run pip in isolated mode, ignores environment variables and user configuration]' \ {-v,--verbose}'[give more output]' \ {-V,--version}'[show version number of program and exit]' \ {-q,--quiet}'[give less output]' \ '--log[log file location]' \ '--proxy=[proxy in form user:passwd@proxy.server:port]' \ '--retries=[max number of retries per connection (default 5 times)]' \ '--timeout=[socket timeout (default 15s)]' \ '--exists-action=[default action when a path already exists: (s)witch, (i)gnore, (w)ipe, (b)ackup]' \ '--trusted-host=[mark this host as trusted]' \ '--cert=[path to alternate CA bundle]' \ '--client-cert=[path to SSL client certificate]' \ '--cache-dir=[store the cache data in specified directory]' \ '--no-cache-dir[disable de cache]' \ '--disable-pip-version-check[do not check periodically for new pip version downloads]' \ {-E,--environment}'[virtualenv environment to run pip in (deprecated)]' \ {-s,--enable-site-packages}'[include site-packages in virtualenv (deprecated)]' \ '1: :__pip_commands' \ '*::arg:->args' case "$state" in (args) curcontext="${curcontext%:*:*}:pip_${words[1]}:" # check if a command with a defined completion was typed type _pip_${words[1]} &> /dev/null if [[ $? != 1 ]]; then _pip_${words[1]} fi esac