#compdef paket=paket.exe paket.exe # Zsh completion script for Paket (https://github.com/fsprojects/Paket/). # # This script is based on the excellent git complection in zsh. Many thanks # to its authors! # # # INSTALLATION # # 1. Download the paket-completion.zsh file to a subdirectory of your home # directory, preferably a directory with other function files. # 2. Rename it to _paket. # 3. Add the directory to your zsh fpath before running compinit. # # $ target="$HOME/.zsh-completions" # $ mkdir "$target" # $ curl --fail --location --proto-redir -all,https --output "$target/_paket" https://raw.githubusercontent.com/fsprojects/Paket/master/completion/paket-completion.zsh # # In your ~/.zshrc: # # fpath=($HOME/directory/where/_paket/resides $fpath) # # # UPDATING AN EXISTING INSTALLATION # # Just repeat the download from above. # # Alternatively the completion script comes bundled with the # paket-completion-update function that will download the current # paket-completion.zsh to the same file as above, even if you changed its # location after the initial download. # # Please note: The paket-completion-update function requires curl to be # installed. paket-completion-update is *only available after your # first paket completion* per shell session (i.e. after the Paket completion # functions have been autoloaded by zsh). # # paket-completion-update supports an optional first parameter that allows you # to override the default download root URL which is # https://raw.githubusercontent.com/fsprojects/Paket/master/completion. # # # PAKET ALIAS # # For easier consumption of Paket (without paket.sh or paket.cmd) it is advised # to create an alias and always run Paket from the repository root. # # Also have a look at Paket's magic mode. # https://fsprojects.github.io/Paket/bootstrapper.html#Magic-mode # # Somewhere in your ~/.zshrc: # # if [[ "$OS" != Windows* ]]; then # alias paket='mono ./.paket/paket.exe' # else # alias paket='./.paket/paket.exe' # fi # # Also ensure that zsh completes aliases based on the expanded alias contents. # http://zsh.sourceforge.net/Doc/Release/Options.html#index-COMPLETEALIASES # # unsetopt completealiases # # If you don't like alias completion, define that the paket alias should be # completed using the _paket function defined in this file. # # setopt completealiases # compdef _paket paket # # # MONO # # If you use Mono (e.g. on Linux or macOS) and do not have Mono completion # installed, you need to define that mono invokes other programs: # # compdef _precommand mono # # This is similar to `nohup` invoking the "real" program that needs to be # completed. More details: https://unix.stackexchange.com/a/178054/72946 # # For an exemplar mono completion, have a look here: # https://github.com/agross/dotfiles/tree/master/mono/functions/_mono # # # CONFIGURATION # # You can configure some aspects of Paket completion. Add these to your # ~/.zshrc. # # Define where to look for paket.exe # # Depending on what should be completed the Paket executable will be run by # the completion script. The completion script searches for a local # installation at ./.paket/paket.exe first. Local installs will be prepended # with mono unless you are running Windows. Global installations will be # looked at last (i.e. paket in the $PATH). They are not prepended with # mono. # # To override the list of possible locations for local installations of # paket.exe, define the following `paket-executable` style. The list of values # will be searched as defined. # # # This is the default. # zstyle ':completion::complete:paket:*' paket-executable './.paket/paket.exe' # # Useful for Paket developers: Prefer the locally built version in bin over the one in .paket. # zstyle ':completion::complete:paket:*' paket-executable './bin/paket.exe' './.paket/paket.exe' # # # Enable infix matching for package IDs # # By default paket find-packages will match infixes, which is not the default # mode for Paket completion. I think it's unnatural to type # paket add FAK # which will be completed to # paket add Altairis.Fakturoid.Client # if infix matching is enabled. # # If you want this behavior, enable infix matches: # # zstyle ':completion::complete:paket:*' infix-match yes # zstyle ':completion::complete:paket:add:*' infix-match yes # Only for paket add. # # # Disable fallback (i.e. default zsh) completion for Paket commands that do not # have a completion function: # # zstyle ':completion::complete:paket:*' use-fallback no # # # Disable verbose completion of main commands: # # zstyle ':completion::complete:paket:*' verbose no # # # Define the zsh completion cache policy for expensive operations that generate # completions. # # Paket will e.g. issue HTTP requests when you complete a package ID or a # version number. These take time so we take advantage of the zsh # completion cache and store such results. # # Enable the zsh completion cache globally, including completions for other # commands that also leverage caching: # # zstyle ':completion:*' use-cache on # zstyle ':completion:*' cache-path instead/of/$HOME/.zcompcache # Optional. # # To disable the cache for specific Paket commands to always get fresh # results when completing e.g. paket add: # # zstyle ':completion::complete:paket:add:*' use-cache off # # The caches are stored under the cache-path as follows: # # /paket// # # e.g. # # /paket/find-packages/fak # # if you completed 'paket find-packages FAK' or 'paket find-packages fak' # before. # # The default cache policy caches results for 1 day (see _paket_cache_policy). # To remove cached results you can either delete the # /paket directory or provide a custom cache policy to control # cache expiration for all or specific Paket commands: # # zstyle ':completion::complete:paket:*' cache-policy _default_cache_policy # zstyle ':completion::complete:paket:find-packages:*' cache-policy _strict_cache_policy # # _default_cache_policy () { # # Rebuild if the cache is more than a week old. # local file="$1" # local -a outdated # # See http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers # outdated=( "$file"(Nm+7) ) # (( $#outdated )) # } # # _strict_cache_policy () { # return 0 # 0 == always outdated, you should better use use-cache off. # } # # There are two special default cache policies for completions relying on the # existence of local files, e.g. paket.dependencies or paket.lock. # For Paket commands that read these, the cache is invalidated as soon as the # file's modification time is newer than the cache. # (See _paket_cache_policy_dependencies_file and # _paket_cache_policy_lock_file.) # # # Disable running Paket to get packages, versions etc. as completion arguments # # Disable globally: # # zstyle ':completion::complete:paket:*' disable-completion yes # # Disable only a single means to get completion values: # # # Used by e.g. paket add: # zstyle ':completion::complete:paket:find-packages:' disable-completion yes # zstyle ':completion::complete:paket:find-package-versions:' disable-completion yes # zstyle ':completion::complete:paket:show-groups:' disable-completion yes # # # Used by e.g. paket why: # zstyle ':completion::complete:paket:show-installed-packages:' disable-completion yes # # # Custom feed URLs for --source and paket push --url argument # # Define additional sources that will be completed for all Paket commands: # # zstyle ':completion::complete:paket:*' sources 'http://one.example.com/feed/v2' # zstyle ':completion::complete:paket:*' sources \ # 'http://one.example.com/feed/v2' \ # 'http://second.example.com/feed/v2' # # Override list for a specific command: # # zstyle ':completion::complete:paket:find-package-versions:*' sources \ # 'http://another.example.com/feed/v2' # zstyle ':completion::complete:paket:push:*' sources \ # 'https://myget.org/F/my-feed-name' _paket() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args # Strip .exe extension. curcontext="${curcontext%.*}:" # Set up default cache policy. local -A default_policies default_policies[${curcontext}*]=_paket_cache_policy default_policies[${curcontext}*:*:show-groups:]=_paket_cache_policy_dependencies_file default_policies[${curcontext}*:*:show-installed-packages:]=_paket_cache_policy_lock_file local key cache_policy for key in "${(@kO)default_policies}"; do local ctx="$key" local policy="${default_policies[$key]}" zstyle -s ":completion:$ctx" cache-policy cache_policy if [[ -z "$cache_policy" ]]; then zstyle ":completion:$ctx" cache-policy $policy fi done # Do not offer anything after these options. local -a terminating_options terminating_options=( '(- :)'--version'[show Paket version]' ) # Currently not implemented: # ! means that if these options were specified right after paket, do not # offer them as completions for the command. # E.g. paket --verbose install -- won't show verbose again local -a global_options global_options=( '(- :)'--help'[display help]' '(--log-file)'--log-file'[print output to a file]:log file:_files' '(-s --silent)'{-s,--silent}'[suppress console output]' '(-v --verbose)'{-v,--verbose}'[print detailed information to the console]' ) local -a keep_options keep_options=( '(--keep-major --keep-minor --keep-patch)'--keep-major'[only allow updates that preserve the major version]' '(--keep-major --keep-minor --keep-patch)'--keep-minor'[only allow updates that preserve the minor version]' '(--keep-major --keep-minor --keep-patch)'--keep-patch'[only allow updates that preserve the patch version]' ) local -a binding_redirects_options binding_redirects_options=( '(--redirects)'--redirects'[create binding redirects]' '(--clean-redirects)'--clean-redirects'[remove binding redirects that were not created by Paket]' '(--create-new-binding-files)'--create-new-binding-files'[create binding redirect files if needed]' ) local -a download_options download_options=( '(-f --force)'{-f,--force}'[force download and reinstallation of all dependencies]' '(--touch-affected-refs)'--touch-affected-refs'[touch project files referencing affected dependencies to help incremental build tools detecting the change]' ) # --verbose, --log-file and --silent (see above) # These can appear as the first option, optionally followed by a command. # # --version and --help (see above) # No more options are allowed afterwards. # # command # Does not start with dash. # # option-or-argument # This is the "rest" argument. # # For more information, see http://zsh.sourceforge.net/Doc/Release/Completion-System.html # and search for "Each of the forms above may be preceded by a list in # parentheses of option names and argument numbers". _arguments -C \ $terminating_options \ $global_options \ '(-): :->command' \ '(-)*:: :->option-or-argument' \ && ret=0 case "$state" in (command) _paket_commands && ret=0 ;; (option-or-argument) # Construct :complete:paket::. curcontext="${curcontext%:*}:${words[1]}:" if ! _call_function ret "_paket-${words[1]}"; then _message "Completion for Paket command '${words[1]}' is not implemented, please contact @agross" if zstyle -T ":completion:$curcontext:" use-fallback; then _default && ret=0 fi fi ;; esac return ret } (( $+functions[_paket_group_option] )) || _paket_group_option() { print -l '(--group -g)'{--group,-g}"[$1]:group:_paket_groups" } (( $+functions[_paket_source_url] )) || _paket_source_url() { local state="$1" curcontext="${2%:*}" ret=1 case $state in (source-url) local -a user_sources zstyle -a ":completion:$curcontext:" sources user_sources local -a args args=( 'source::_paket_sources' 'NuGet.org feed:NuGet.org feed:(https://www.nuget.org/api/v2 https://api.nuget.org/v3/index.json)' "user-defined feed:user-defined feed:($user_sources)" 'urls::_urls' ) _alternative \ $args \ && ret=0 ;; esac return ret } (( $+functions[_paket-add] )) || _paket-add() { local curcontext=$curcontext context state state_descr ret=1 typeset -A opt_args local -a line local -a args args=( $global_options $keep_options $binding_redirects_options $download_options '(--interactive -i)'{--interactive,-i}"[ask for every project whether to add the dependency]" '(--no-install)'--no-install'[do not modify projects]' '(--no-resolve)'--no-resolve'[do not resolve]' '(--project -p)'{--project,-p}'[add the dependency to a single project only]:project:_path_files -g "**/*.??proj"' '(--type -t)'{--type,-t}"[type of the dependency (default: nuget)]:dependency type:((\ nuget\:'add NuGet dependency' \ clitool\:'add .NET Core CLI tool'))" '(--version -V)'{--version,-V}'[dependency version constraint]: :->version' "${(f)$(_paket_group_option 'add the dependency to a group (default: Main group)')}" ) _arguments -C \ $args \ ':NuGet package ID:->package-id' \ && return case $state in (package-id) _paket_packages && ret=0 ;; (version) _paket_version_constraint && ret=0 ;; esac return ret } (( $+functions[_paket-auto-restore] )) || _paket-auto-restore() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options ) _arguments -C \ $args \ '1: :->mode' \ && ret=0 case $state in (mode) local -a modes modes=( 'on:enable automatic restore' 'off:disable automatic restore' ) _describe -t modes mode modes \ && ret=0 ;; esac return ret } (( $+functions[_paket-clear-cache] )) || _paket-clear-cache() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '(--clear-local)'--clear-local"[also clear local packages and paket-files directory]" ) _arguments -C \ $args \ && ret=0 return ret } (( $+functions[_paket-config] )) || _paket-config() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options ) _arguments -C \ $args \ ': :->command' \ '*:: :->option-or-argument' \ && ret=0 case $state in (command) local -a commands commands=( 'add-credentials:add credentials for URL or credential key' 'add-token:add token for URL or credential key' ) _describe -t commands command commands \ && ret=0 ;; (option-or-argument) curcontext=${curcontext%:*}-$line[1]: case $line[1] in (add-credentials) _arguments -C \ $args \ '(--authtype)'--authtype'[authentication type (default: basic)]:authentication type:(basic ntlm)' \ '(--username)'--username'[provide username]:user name: ' \ '(--password)'--password'[provide password]:password: ' \ '(--verify)'--verify'[verify credentials]' \ '1: :->source-url-or-credential-key' \ && ret=0 case $state in (source-url-or-credential-key) _alternative \ 'source::_paket_sources' \ 'credential key::_paket_credential_keys' \ 'urls::_urls' \ && ret=0 ;; esac ;; (add-token) _arguments -C \ $args \ '1: :->source-url-or-credential-key' \ '2:token' \ && ret=0 case $state in (source-url-or-credential-key) _alternative \ 'source::_paket_sources' \ 'credential key::_paket_credential_keys' \ ' :URL to set NuGet.org API key:(https://www.nuget.org)' \ 'urls::_urls' \ && ret=0 ;; esac ;; esac esac return ret } (( $+functions[_paket-convert-from-nuget] )) || _paket-convert-from-nuget() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '(-f --force)'{-f,--force}'[force the conversion even if paket.dependencies or paket.references files are present]' '(--no-install)'--no-install'[do not modify projects]' '(--no-auto-restore)'--no-auto-restore"[do not enable automatic package restore]" '(--migrate-credentials)'--migrate-credentials"[specify mode for NuGet source credential migration (default: encrypt)]:credential migration mode:((\ encrypt\:'store encrypted in paket.config (default)' \ plaintext\:'store as plain text in paket.dependencies' \ selective\:'be asked for every feed'))" ) _arguments -C \ $args \ && ret=0 return ret } (( $+functions[_paket-find-refs] )) || _paket-find-refs() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options "${(f)$(_paket_group_option 'specify dependency group (default: Main group)')}" ) _arguments -C \ $args \ '*: :->package-id' \ && ret=0 case $state in (package-id) local group=${(v)opt_args[(i)--group|-g]:-Main} _paket_installed_packages $group --all \ && ret=0 ;; esac return ret } (( $+functions[_paket-find-package-versions] )) || _paket-find-package-versions() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '(--source)'--source'[specify source URL]: :->source-url' '(--max)'--max'[limit maximum number of results]:maxiumum results:(1 5 10 50 100 1000)' ) _arguments -C \ $args \ ':NuGet package ID:_paket_packages' \ && ret=0 _paket_source_url "$state" "$curcontext" && ret=0 return ret } (( $+functions[_paket-find-packages] )) || _paket-find-packages() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '(--source)'--source'[specify source URL]: :->source-url' '(--max)'--max'[limit maximum number of results]:maxiumum results:(1 5 10 50 100 1000)' ) _arguments -C \ $args \ ':NuGet package ID:_paket_packages' \ && ret=0 _paket_source_url "$state" "$curcontext" && ret=0 return ret } (( $+functions[_paket-generate-load-scripts] )) || _paket-generate-load-scripts() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '*'{-f,--framework}'[framework identifier to generate scripts for]:framework: ' '*'{-t,--type}'[language to generate scripts for]: :->language' '*'{-g,--group}'[group to generate scripts for (default: all groups)]: :->group' ) _arguments -C \ $args \ && ret=0 case $state in (language) local -a languages languages=(${(v@Qs_:_)opt_args[(I)--type|-t]}) _paket_languages -F languages \ && ret=0 ;; (group) local -a groups # Search --group and -g optargs for values (v), make array (@) and # remove quotes (Q) and split by : (s_:_). groups=(${(v@Qs_:_)opt_args[(I)--group|-g]}) _paket_groups -F groups \ && ret=0 ;; esac return ret } (( $+functions[_paket-init] )) || _paket-init() { _arguments $global_options } (( $+functions[_paket-info] )) || _paket-info() { local curcontext=$curcontext context state state_descr ret=1 typeset -A opt_args local -a line local -a args args=( $global_options '(--paket-dependencies-dir)'--paket-dependencies-dir'[shows the absolute path of the directory containing paket.dependencies, if it exists]' ) _arguments -C \ $args \ && ret=0 return ret } (( $+functions[_paket-install] )) || _paket-install() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options $keep_options $binding_redirects_options $download_options '(--only-referenced)'--only-referenced'[only install dependencies listed in paket.references files, instead of all packages in paket.dependencies]' '(--generate-load-scripts)'--generate-load-scripts'[generate F# and C# include scripts that reference installed packages in a interactive environment like F# Interactive or ScriptCS]' '*--load-script-framework[framework identifier to generate scripts for]:framework: ' '*--load-script-type[language to generate scripts for]: :->language' ) _arguments -C \ $args \ && ret=0 case $state in (language) local -a languages languages=(${(vQs_:_)opt_args[(i)--load-script-type]}) _paket_languages -F languages \ && ret=0 ;; esac return ret } (( $+functions[_paket-outdated] )) || _paket-outdated() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options "${(f)$(_paket_group_option 'specify dependency group (default: all groups)')}" '(-f --force)'{-f,--force}'[force download and reinstallation of all dependencies]' '(--ignore-constraints)'--ignore-constraints'[ignore version constraints in the paket.dependencies file]' '(--pre --include-prereleases)'{--pre,--include-prereleases}'[consider prerelease versions as updates]' ) _arguments -C \ $args \ && ret=0 return ret } (( $+functions[_paket-pack] )) || _paket-pack() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '(--build-config)'--build-config'[build configuration that should be packaged (default: Release)]:build configuration: ' '(--build-platform)'--build-platform'[build platform that should be packaged (default: check all known platform targets)]:build platform: ' '(--version)'--version'[version of the package]:version: ' '(--template)'--template'[pack a single paket.template file]:template:_path_files -g "**/paket.template"' '*--exclude[exclude paket.template file by package ID]: :->template-id' '*--specific-version[version number to use for package ID]: :->specific-version' '(--release-notes)'--release-notes'[release notes]:release notes: ' '(--lock-dependencies)'--lock-dependencies'[use version constraints from paket.lock instead of paket.dependencies]' '(--minimum-from-lock-file)'--minimum-from-lock-file'[use version constraints from paket.lock instead of paket.dependencies and add them as a minimum version; --lock-dependencies overrides this option]' '(--pin-project-references)'--pin-project-references'[pin dependencies generated from project references to exact versions (=) instead of using minimum versions (>=); with --lock-dependencies project references will be pinned even if this option is not specified]' '(--symbols)'--symbols'[create symbol and source packages in addition to library and content packages]' '(--include-referenced-projects)'--include-referenced-projects'[include symbols and source from referenced projects]' '(--project-url)'--project-url'[homepage URL for the package]:URL:_urls' ) _arguments -C \ $args \ ':output directory for .nupkg files:_directories' \ && ret=0 case $state in (template-id) local -a ids ids=(${(vQs_:_)opt_args[(i)--exclude]}) _paket_template_ids -F ids \ && ret=0 ;; (specific-version) _message 'TODO, not implemented' \ && ret=0 ;; esac return ret } (( $+functions[_paket-push] )) || _paket-push() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '(--url)'--url'[URL of the NuGet feed]: :->url' '(--api-key)'--api-key'[API key for the URL (default: value of the NUGET_KEY environment variable)]:API key: ' '(--endpoint)'--endpoint'[API endpoint to push to (default: /api/v2/package))]:endpoint: ' ) _arguments -C \ $args \ '1:NuGet package:_path_files -g "(^packages/)#/*.nupkg"' \ && ret=0 case $state in (url) local -a user_sources zstyle -a ":completion:$curcontext:" sources user_sources local -a args args=( 'source::_paket_sources' 'NuGet.org feed:NuGet.org feed:(https://www.nuget.org/)' "user-defined feed:user-defined feed:($user_sources)" 'urls::_urls' ) _alternative \ $args \ && ret=0 ;; esac return ret } (( $+functions[_paket-remove] )) || _paket-remove() { local curcontext=$curcontext context state state_descr ret=1 typeset -A opt_args local -a line local -a args args=( $global_options '(-f --force)'{-f,--force}'[force download and reinstallation of all dependencies]' '(--interactive -i)'{--interactive,-i}"[ask for every project whether to remove the dependency]" '(--no-install)'--no-install'[do not modify projects]' '(--project -p)'{--project,-p}'[remove the dependency from a single project only]:project:_path_files -g "**/*.??proj"' "${(f)$(_paket_group_option 'remove the dependency from a group (default: Main group)')}" ) _arguments -C \ $args \ ':NuGet package ID:->package-id' \ && return case $state in (package-id) local group=${(v)opt_args[(i)--group|-g]} _paket_installed_packages $group \ && ret=0 ;; esac return ret } (( $+functions[_paket-restore] )) || _paket-restore() { local curcontext=$curcontext context state state_descr ret=1 typeset -A opt_args local -a line local -a args args=( $global_options $download_options '*--references-file[restore packages from a paket.references file]:paket.references:_path_files -g "**/*paket.references"' '(--only-referenced)'--only-referenced'[only restore packages that are referenced by paket.references files]' '(--project -p)'{--project,-p}'[restore dependencies of a single project]:project:_path_files -g "**/*.??proj"' '(--target-framework)'--target-framework'[restore only for the specified target framework]:target framework: ' '(--ignore-checks --fail-on-checks)'--ignore-checks'[do not check if paket.dependencies and paket.lock are in sync]' '(--ignore-checks --fail-on-checks)'--fail-on-checks'[abort if any checks fail]' "${(f)$(_paket_group_option 'restore dependencies of a single group')}" ) _arguments -C \ $args \ && return return ret } (( $+functions[_paket-restriction] )) || _paket-restriction() { local curcontext=$curcontext context state state_descr ret=1 typeset -A opt_args local -a line _arguments -C \ $global_options \ '1:Paket formula representing a restriction' \ && ret=0 return ret } (( $+functions[_paket-show-groups] )) || _paket-show-groups() { _arguments $global_options } (( $+functions[_paket-show-installed-packages] )) || _paket-show-installed-packages() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '(-p --project)'{-p,--project}'[specify project to show dependencies for]:project:_path_files -g "**/*.??proj"' '(-a --all)'--all'[include transitive dependencies]' ) _arguments -C \ $args \ && ret=0 return ret } (( $+functions[_paket-simplify] )) || _paket-simplify() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '(-i --interactive)'{-i,--interactive}'[confirm deletion of every transitive dependency]' ) _arguments -C \ $args \ && ret=0 return ret } (( $+functions[_paket-update] )) || _paket-update() { local curcontext=$curcontext context state state_descr ret=1 typeset -A opt_args local -a line local -a args args=( $global_options $keep_options $binding_redirects_options $download_options '(--filter)'--filter'[treat the NuGet package ID as a regex to filter packages]' '(--no-install)'--no-install'[do not modify projects]' '(--version -V)'{--version,-V}'[dependency version constraint]: :->version' "${(f)$(_paket_group_option 'specify dependency group to update (default: all groups)')}" ) _arguments -C \ $args \ ':NuGet package ID:->package-id' \ && return case $state in (package-id) local group=${(v)opt_args[(i)--group|-g]} _paket_installed_packages $group \ && ret=0 ;; (version) _paket_version_constraint && ret=0 ;; esac return ret } (( $+functions[_paket-why] )) || _paket-why() { local curcontext=$curcontext context state state_descr line ret=1 typeset -A opt_args local -a args args=( $global_options '(--details)'--details'[display detailed information with all paths, versions and framework restrictions]' "${(f)$(_paket_group_option 'specify dependency group (default: Main group)')}" ) _arguments -C \ $args \ ': :->package-id' \ && ret=0 case $state in (package-id) local group=${(v)opt_args[(i)--group|-g]:-Main} _paket_installed_packages $group --all \ && ret=0 ;; esac return ret } (( $+functions[_paket_commands] )) || _paket_commands() { local -a types types=( dependency inspection NuGet misc ) for type in $types; do local -a $type done dependency=( add:'add a new dependency' install:'download dependencies and update projects' outdated:'find dependencies that have newer versions available' remove:'remove a dependency' restore:'download the computed dependency graph' simplify:'simplify declared dependencies by removing transitive dependencies' update:'update dependencies to their latest version' ) inspection=( find-packages:'search for NuGet packages' find-package-versions:'search for dependency versions' find-refs:'find all project files that have a dependency installed' restriction:'resolve a framework restriction and show details' show-groups:'show groups' show-installed-packages:'show installed dependencies' why:'determine why a dependency is required' ) NuGet=( convert-from-nuget:'convert projects from NuGet to Paket' pack:'create NuGet packages from paket.template files' push:'push a NuGet package' ) misc=( auto-restore:'manage automatic package restore during the build process inside Visual Studio' clear-cache:'clear the global and optionally local NuGet and cache directories' config:'store global configuration values like NuGet credentials' generate-load-scripts:'generate F# and C# include scripts that reference installed packages in a interactive environment like F# Interactive or ScriptCS' init:'create an empty paket.dependencies file in the current working directory' info:'show information about the current project' ) for type in $types; do local -a all_commands "${type}_commands" # Remove everything after the colon of the command definition above. set -A "${type}_commands" ${(P)type%%:*} # Copy command list to all_commands. all_commands+=(${(P)${:-${type}_commands}}) done # To get the length of the longest matching command, filter the list of # commands down to the prefix the user typed. # Get applicable matchers. local expl _description '' expl '' local -a all_matching_commands compadd "$expl[@]" -O all_matching_commands -a -- all_commands # Length of longest match. longest_match=${#${(O)all_matching_commands//?/.}[1]} # Verbose/long display requested? local -a disp if zstyle -T ":completion:$curcontext:" verbose; then disp=(-ld '${type}_desc') fi local -a alternatives for type in $types; do local -a "${type}_desc" # Write description: # 1. command padded with spaces up to longest_match # 2. ' -- ' # 3. description, trimmed if longer than screen width set -A "${type}_desc" \ ${${(r.$COLUMNS-1.)${(P)type}/(#s)(#m)[^:]##:/${(r.longest_match.)MATCH[1,-2]} -- }%% #} alternatives+=("${type}:$type command:compadd ${(e)disp} -a -- ${type}_commands") done _alternative $alternatives } (( $+functions[_paket_packages] )) || _paket_packages() { local cmd=find-packages local what='NuGet package ID' if ! _paket_should_run $cmd; then _message "Enter $what" return fi local package_id="${words[$CURRENT]}" local cache_id="${service%.*}/$cmd/${(L)package_id:-_}" if ! _retrieve_cache $cache_id; then # We need to replace CR, in case we're running on Windows (//$'\r'/). local -a output output=( ${(f)"$(_call_program $cmd \ "$(_paket_executable) $cmd --silent --max 100 '$package_id' 2> /dev/null")"//$'\r'/} ) _paket_command_successful $? || return 1 _store_cache $cache_id output fi local infix_match local -a compadd_args if zstyle -b ":completion:${curcontext}" infix-match infix_match; then compadd_args=(-U) fi local expl _wanted paket-packages expl $what \ compadd $compadd_args \ -M 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' -a - output } (( $+functions[_paket_package_versions] )) || _paket_package_versions() { local cmd=find-package-versions local what='version' if ! _paket_should_run $cmd; then _message "Enter $what" return fi local package_id="${line[1]}" if [[ -z "$package_id" ]]; then _message 'Cannot complete version without NuGet package ID' return 1 fi local constraint="$IPREFIX" local cache_id="${service%.*}/$cmd/${(L)package_id:-_}" if ! _retrieve_cache $cache_id; then # We need to replace CR, in case we're running on Windows (//$'\r'/). local -a output output=( ${(f)"$(_call_program $cmd \ "$(_paket_executable) $cmd --silent --max 100 '$package_id' 2> /dev/null")"//$'\r'/} ) _paket_command_successful $? || return 1 _store_cache $cache_id output fi # If the there is a constraint, also complete fake values, # e.g. 1.2.3 adds 1.2 and 1. local -a fake_versions if [[ -n "$constraint" ]]; then local version index for version in $output; do local -a parts=(${(s:.:)version}) for (( index = 1; index <= $#parts; index++ )); do local -a up_to_index=(${parts[1,index]}) version=${(j:.:)up_to_index} fake_versions+=$version done done # Remove fake versions that are real versions. fake_versions=(${fake_versions:|output}) fi local expl _wanted paket-package-versions expl "$what for $package_id" \ compadd -a -- output _wanted paket-fake-package-versions expl "fake $what for $package_id" \ compadd -n -a -- fake_versions } (( $+functions[_paket_groups] )) || _paket_groups() { local cmd=show-groups local what='group' if ! _paket_should_run $cmd; then _message "Enter $what" return fi # Modify context for cache retrieval only. local curcontext="$curcontext:$cmd" local cache_id="${service%.*}/$cmd/${PWD//\//-}" if ! _retrieve_cache $cache_id; then # We need to replace CR, in case we're running on Windows (//$'\r'/). local -a output output=( ${(f)"$(_call_program $cmd \ "$(_paket_executable) $cmd --silent 2> /dev/null")"//$'\r'/} ) _paket_command_successful $? || return 1 _store_cache $cache_id output fi local expl _wanted paket-groups expl $what compadd -a $@ -- output } (( $+functions[_paket_installed_packages] )) || _paket_installed_packages() { local group="$1" local args=$* local cmd=show-installed-packages local what='NuGet package ID' [[ -n "$group" ]] && what="$what for group $group" if ! _paket_should_run $cmd; then _message "Enter $what" return fi # Modify context for cache retrieval only. local curcontext="$curcontext:$cmd" local cache_id="${service%.*}/$cmd/${PWD//\//-}" if ! _retrieve_cache $cache_id; then local -a output output=( ${(f)"$(_call_program $cmd \ "$(_paket_executable) $cmd $args --silent 2> /dev/null")"} ) _paket_command_successful $? || return 1 _store_cache $cache_id output fi # Filter packages by optional group name followed by space. [[ -n "$group" ]] && output=(${(M)output:#$group *}) # Take the second word (the package ID). # Format: - output=(${output/(#m)*/${MATCH[(w)2]}}) # -F line: exclude $line elements as possible completions (i.e. remove # packages already typed). local expl _wanted paket-installed-packages expl $what compadd -F line -a -- output } (( $+functions[_paket_sources] )) || _paket_sources() { local -a output output=( ${(f)"$(_call_program sources \ "grep '^\s*source\s\+\S' paket.dependencies 2> /dev/null")"} ) (( $? == 0 )) || return 1 # Take the second word (the source URL). # Format: source URL ... output=(${output/(#m)*/${MATCH[(w)2]}}) local expl _wanted paket-sources expl 'source URL' compadd -a -- output } (( $+functions[_paket_credential_keys] )) || _paket_credential_keys() { local -a output output=( ${(f)"$(_call_program credential-keys \ "grep '^\s*github\(\s\+\S\+\)\{3\}' paket.dependencies 2> /dev/null")"} ) (( $? == 0 )) || return 1 # Take the fourth word (the credential key). # Format: github repo file credential-key output=(${output/(#m)*/${MATCH[(w)4]}}) local expl _wanted paket-credential-keys expl 'credential key' compadd -a -- output } (( $+functions[_paket_template_ids] )) || _paket_template_ids() { local -a output output=( ${(f)"$(_call_program template_ids \ "grep -r '^id\s\+\S' **/*paket.template 2> /dev/null")"} ) (( $? == 0 )) || return 1 # TODO: Check for 'type project' templates and determine IDs from ??proj. # src/Paket.Bootstrapper/paket.template is a good example. # Take the second word (the package ID). # Format: id package-id output=(${output/(#m)*/${MATCH[(w)2]}}) local expl _wanted paket-template-ids expl 'template package ID' compadd -a $@ -- output } (( $+functions[_paket_languages] )) || _paket_languages() { local -a args desc args=( fsx csx ) desc=( 'fsx for F# Interactive' 'csx for ScriptCS' ) local expl _wanted paket-language expl 'language' compadd -a -ld desc $@ -- args } (( $+functions[_paket_strategy_modifiers] )) || _paket_strategy_modifiers() { local -a args args=( '@:use maximum versions for transitive dependencies' '!:use minimum versions for transitive dependencies' ) _describe -t paket-strategy-modifier 'strategy modifier' args -qS '' } (( $+functions[_paket_version_constraints] )) || _paket_version_constraints() { local -a args args=( '~>:pessimistic (i.e. ~> 1.0 equals >= 1.0 and < 2.0)' '=:pin version' '==:exact version' '=>:at least' '>:greater than' '<=:less than or equal' '<:less than' ) _describe -t paket-version-constraint 'version constraint' args -qS '\ ' } (( $+functions[_paket_version_constraint] )) || _paket_version_constraint() { if compset -P '* '; then # For some reason an ! properly escaped on the command line will # unescaped when generating more completions. [[ "$IPREFIX" == !* ]] && IPREFIX='\!'${IPREFIX[2,-1]} _paket_package_versions && ret=0 elif compset -P '!' || compset -P '@'; then # For some reason an ! properly escaped on the command line will # unescaped when generating more completions. [[ "$IPREFIX" == !* ]] && IPREFIX='\!'${IPREFIX[2,-1]} _paket_version_constraints && ret=0 else _alternative \ "strategy-modifier::_paket_strategy_modifiers" \ "version-constraint::_paket_version_constraints" \ "package-version::_paket_package_versions" \ && ret=0 fi } (( $+functions[_paket_should_run] )) || _paket_should_run() { local key=":completion:${curcontext%:*:*}:${1?Need type}:" local disable_completion if zstyle -b "$key" disable-completion disable_completion; then return 1 fi return 0 } (( $+functions[_paket_command_successful] )) || _paket_command_successful () { if (( $1 > 0 )); then _message "${2:-paket} invocation failed with exit status $1" return 1 fi return 0 } (( $+functions[_paket_executable] )) || _paket_executable() { local -a locations if ! zstyle -a ":completion:$curcontext:" paket-executable locations; then locations=(./.paket/$service) fi if [[ $OS != Windows* ]]; then local mono=mono fi local location for location in $locations; do [[ -f "$location" ]] && printf '%s "%s"' "$mono" "$location" && return done if (($+commands[paket])); then printf '"%s"' "$commands[paket]" && return fi return 1 } (( $+functions[_paket_cache_policy] )) || _paket_cache_policy() { local cache="$1" # Rebuild if the cache is more than a day old. # See http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers local -a outdated outdated=("$cache"(mh+24)) (( $#outdated )) && return 0 # Still fresh! return 1 } (( $+functions[_paket_cache_policy_dependencies_file] )) || _paket_cache_policy_dependencies_file() { local cache="$1" # Rebuild if paket.dependencies is newer than cache. if [[ ! -f paket.dependencies || paket.dependencies -nt $cache ]]; then return 0 fi return 1 } (( $+functions[_paket_cache_policy_lock_file] )) || _paket_cache_policy_lock_file() { local cache="$1" # Rebuild if paket.dependencies is newer than cache. if [[ ! -f paket.lock || paket.lock -nt $cache ]]; then return 0 fi return 1 } (( $+functions[paket-completion-update] )) || paket-completion-update() { local download_from="${1:-https://raw.githubusercontent.com/fsprojects/Paket/master/completion}" # entries are files under $download_from pointing to local files. local -A entries # Let the file point to the file defining our function, even if it is # symlinked. # http://stackoverflow.com/a/28336473/149264 # https://unix.stackexchange.com/a/136565/72946 entries[paket-completion.zsh]=${${(%):-%x}:A} local key for key in "${(@k)entries}"; do local file="$key" local target="${entries[$key]}" if [[ -z "$target" ]]; then >&2 printf 'Could not determine target file for "%s"\n' "$file" return 1 fi if [[ ! -f "$target" ]]; then >&2 printf 'Target file %s for %s does not exist\n' "$target" "$file" return 1 fi local url="$download_from/$file" printf 'Downloading %s to %s\n' "$url" "$target" if ! curl --fail \ --location \ --proto-redir -all,https \ "$url" \ --output "$target"; then >&2 printf 'Error while downloading %s to %s\n' "$url" "$target" return 1 fi done printf 'Paket completion was updated. Please restart your shell.\n' } _paket "$@" # vim: ft=zsh sw=2 ts=2 et