From 4bd7b7547fda2e8cc075b0bd0f5d27a91b4c3a96 Mon Sep 17 00:00:00 2001 From: Timofey Date: Sat, 4 Jan 2014 09:35:58 +0200 Subject: [PATCH 01/13] add support for shutdown command --- src/_shutdown | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/_shutdown diff --git a/src/_shutdown b/src/_shutdown new file mode 100644 index 0000000..f695b9d --- /dev/null +++ b/src/_shutdown @@ -0,0 +1,71 @@ +#compdef shutdown +# ------------------------------------------------------------------------------ +# Copyright (c) 2011 Github zsh-users - http://github.com/zsh-users +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the zsh-users nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------ +# Description +# ----------- +# +# Completion script for shutdown - Shut down the system +# +# ------------------------------------------------------------------------------ +# Authors +# ------- +# +# * Timofey Titovets +# +# ------------------------------------------------------------------------------ +_shutdown(){ + local -a _1st_arguments + _1st_arguments=( + "--help:Show help" + "-H:Halt the machine" "--halt:Halt the machine" + "-P:Power-off the machine" "--poweroff:Power-off the machine" + "-r:Reboot the machine" "--reboot:Reboot the machine" + "-h:Equivalent to --poweroff, overridden by --halt" + "-k:Dont halt/power-off/reboot, just send warnings" + "--no-wall:Dont send wall message before halt/power-off/reboot" + "-c:Cancel a pending shutdown" + ) + + local context state line expl + local -A opt_args + + _arguments '*:: :->subcmds' && return 0 + + if (( CURRENT == 1 )); then + _describe -t commands "shutdown commands" _1st_arguments -V1 + return + fi + + case "$words[1]" in + *) + _arguments \ + ':list option:(now +{0,5,10,15,30} hh:mm)' + ;; + esac +} + +_shutdown "$@" From 2b6e045b242a5e92c516835f3699952b35113704 Mon Sep 17 00:00:00 2001 From: Timofey Date: Sat, 4 Jan 2014 09:37:42 +0200 Subject: [PATCH 02/13] add base completion for xinput Completions for button and property --- src/_xinput | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 src/_xinput diff --git a/src/_xinput b/src/_xinput new file mode 100644 index 0000000..ae2b375 --- /dev/null +++ b/src/_xinput @@ -0,0 +1,196 @@ +#compdef xinput +# ------------------------------------------------------------------------------ +# Copyright (c) 2011 Github zsh-users - http://github.com/zsh-users +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the zsh-users nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------ +# Description +# ----------- +# +# Completion script for xinput +# TODO: Add property handler +# TODO: Add buttons handler +# ------------------------------------------------------------------------------ +# Authors +# ------- +# +# * Timofey Titovets +# +# ------------------------------------------------------------------------------ +_xinput(){ + # list of xinput arguments + local -a _1st_arguments + _1st_arguments=( + 'version:show version' '--version:show version' + 'help:show help options' '--help:show help options' + get-feedbacks + set-ptr-feedback + set-integer-feedback + get-button-map + set-button-map + set-pointer + 'set-mode:change the mode of device' '--set-mode:change the mode of device' + 'list:show devices' '--list:show devices' + query-state + test --test + create-master + remove-master + reattach + float + set-cp + test-xi2 + map-to-output + list-props + set-int-prop + set-float-prop + set-atom-prop + watch-props + delete-prop + set-prop + 'disable:disable the device' '--disable:disable the device' + 'enable:enable the device' '--enable:enable the device' + --get-feedbacks + --set-ptr-feedback + --set-integer-feedback + --get-button-map + --set-button-map + --set-pointer + --query-state + --create-master + --remove-master + --reattach + --float + --set-cp + --test-xi2 + --map-to-output + --list-props + --set-int-prop + --set-float-prop + --set-atom-prop + --watch-props + --delete-prop + --set-prop + ) + + local context state line expl + local -A opt_args + + _arguments '*:: :->subcmds' && return 0 + + if (( CURRENT == 1 )); then + _describe -t commands "xinput commands" _1st_arguments -V1 + return + fi + + _xinput_devices_id=($(xinput list --id-only)) + for i in $(xinput list --id-only) + do + _xinput_devices_name[$i]="$(xinput list --name-only $i)" + done + _xinput_devices=( $_xinput_devices_id $_xinput_devices_name ) + + # xinput arguments handler + case "$words[1]" in + --get-feedbacks|--set-ptr-feedback|--get-button-map|--query-state|--list-props|--watch-props|get-feedbacks|set-ptr-feedback|get-button-map|query-state|list-props|watch-props|--enable|enable|--map-to-output|map-to-output|--disable|disable) + _arguments \ + ':list option:($_xinput_devices)' + ;; + --list|list) + _arguments \ + ':list option:($_xinput_devices --short --long --name-only --id-only)' \ + ':list option:(--short --long --name-only --id-only)' + ;; + --set-integer-feedback|set-integer-feedback) + _arguments \ + ':list option:($_xinput_devices)' \ + ':list option:( feedback )' \ + ':list option:( $_xinput_devices_id )' + ;; + --set-button-map|set-button-map) + _arguments \ + ':list option:($_xinput_devices)' #map button 1 [map button 2 [...]] + ;; + --set-pointer|set-pointer) + _arguments \ + ':list option:($_xinput_devices)' # [x index y index] + ;; + --set-mode|set-mode) + _arguments \ + ':list option:($_xinput_devices)' \ + ':list option:(ABSOLUTE RELATIVE)' + ;; + --test|test) + _arguments \ + ':list option:(-proximity $_xinput_devices )' \ + ':list option:($_xinput_devices)' + ;; + --reattach|reattach) + _arguments \ + ':list option:($_xinput_devices)' \ + ':list option:(master slave)' + ;; + --float|float) + _arguments \ + ':list option:($_xinput_devices_id)' + ;; + --test-xi2|test-xi2) + _arguments \ + ':list option:($_xinput_devices --root)' \ + ':list option:($_xinput_devices)' + ;; + --delete-prop|delete-prop) + _arguments \ + ':list option:($_xinput_devices)' #property + ;; + --create-master|create-master) + _arguments \ + ':list option:($_xinput_devices_id)' # [sendCore (dflt:1)] [enable (dflt:1)] + ;; + --remove-master|remove-master) + _arguments \ + ':list option:($_xinput_devices_id)' # [Floating|AttachToMaster (dflt:Floating)] [returnPointer] [returnKeyboard] + ;; + # --set-cp|set-cp); window device;; + --set-prop|set-prop) + _arguments \ + ':list option:($_xinput_devices)' \ + ':list option:(--type={atom,float,int} --format={8,16,32})' \ + ':list option:(--type={atom,float,int} --format={8,16,32})' # property val [val ...] + ;; + --set-int-prop|set-int-prop) + _arguments \ + ':list option:($_xinput_devices)' # property format (8, 16, 32) val [val ...] + ;; + --set-float-prop|set-float-prop) + _arguments \ + ':list option:($_xinput_devices)' # property val [val ...] + ;; + --set-atom-prop|set-atom-prop) + _arguments \ + ':list option:($_xinput_devices)' # property val [val ...] + ;; + esac +} + +_xinput "$@" From 7187ffd3b73d533aba5e715d2c112f815ac8251b Mon Sep 17 00:00:00 2001 From: Evgeniy Alexeev Date: Wed, 8 Jan 2014 14:54:56 +0300 Subject: [PATCH 03/13] Update _yaourt I have the next function in .zshrc: pacman () { /usr/bin/sudo /usr/bin/pacman $* && echo "$*" | grep -q "S\|R" && rehash } And I have the next line in `/etc/yaourtrc`: PACMAN="/usr/bin/pacman" But if I try to get autocomplite for `yaourt -Ss` (for example) it requires a sudo password. With this patch path to `pacman` (`PACMAN` variable) will be read from the configuration file and this command will not require the password. It is a correct variant :) --- src/_yaourt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/_yaourt b/src/_yaourt index 9a84b04..e9db0da 100644 --- a/src/_yaourt +++ b/src/_yaourt @@ -186,7 +186,9 @@ _yaourt_completions_repositories() { # $cmd must be declared by calling function _yaourt_get_command() { # this is mostly nicked from _perforce - cmd=( "pacman" ) + cmd=$( grep "^PACMAN=" "/etc/yaourtrc" \ + && grep "^PACMAN=" "/etc/yaourtrc" | cut -c8- \ + || echo "pacman" ) integer i for (( i = 2; i < CURRENT - 1; i++ )); do if [[ ${words[i]} = "--config" || ${words[i]} = "--root" ]]; then From 14232ac66daa3e350c5ffa0c576f8516550715b3 Mon Sep 17 00:00:00 2001 From: Evgeniy Alexeev Date: Thu, 9 Jan 2014 03:35:16 +0300 Subject: [PATCH 04/13] Update README.md Edited links to Archlinux packages (the link to *-git is out-of-date, zsh-completion now available in [community]) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 07930e1..9274d0c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Usage #### Using packages -* Arch Linux: [AUR/zsh-completions](https://aur.archlinux.org/packages.php?ID=54111) / [AUR/zsh-completions-git](https://aur.archlinux.org/packages.php?ID=51001) +* Arch Linux: [community/zsh-completions](https://www.archlinux.org/packages/zsh-completions) / [AUR/zsh-completions-git](https://aur.archlinux.org/packages/zsh-completions-git/) * Gentoo: [scrill overlay](http://gpo.zugaina.org/app-shells/zsh-completions) * Mac OS: [Homebrew](https://github.com/mxcl/homebrew/blob/master/Library/Formula/zsh-completions.rb) * Debian based distributions (Debian/Ubuntu/Linux Mint...): Packager needed, please get in touch ! From abc6dccadc8aba3d67a475163c9f0d55b0b75221 Mon Sep 17 00:00:00 2001 From: Sorin Ionescu Date: Tue, 28 Jan 2014 18:35:27 -0500 Subject: [PATCH 05/13] Rename attach to atach --- src/{_attach => _atach} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/{_attach => _atach} (91%) diff --git a/src/_attach b/src/_atach similarity index 91% rename from src/_attach rename to src/_atach index ac0c344..3e6afde 100644 --- a/src/_attach +++ b/src/_atach @@ -1,9 +1,9 @@ -#compdef attach +#compdef atach # ------------------------------------------------------------------------------ # Description # ----------- # -# Completion script for attach (http://github.com/sorin-ionescu/attach). +# Completion script for atach (https://github.com/sorin-ionescu/atach). # # ------------------------------------------------------------------------------ # Authors @@ -21,7 +21,7 @@ mode_values=( "winch:use sigwinch to redraw" ) -existing_sessions=($(_call_program session attach)) +existing_sessions=($(_call_program session atach)) _arguments -C -s -S \ '(--list -l)'{--list,-l}'[list sessions]' \ From 5edeb23f1084c114755dcf1f49058b797d5cc012 Mon Sep 17 00:00:00 2001 From: Luke Steensen Date: Tue, 11 Feb 2014 21:22:44 -0600 Subject: [PATCH 06/13] Add 'services' command to homebrew completion --- src/_brew | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_brew b/src/_brew index 1a94ead..13304dd 100644 --- a/src/_brew +++ b/src/_brew @@ -63,6 +63,7 @@ _1st_arguments=( 'remove:remove a formula' 'search:search for a formula (/regex/ or string)' 'server:start a local web app that lets you browse formulae (requires Sinatra)' + 'services:manage background services via launchctl' 'tap:tap a new formula repository from GitHub, or list existing taps' 'test:a few formulae provide a test method' 'unlink:unlink a formula' From c0ebcbe56b89fe96688c4fce88ae5af40132dc42 Mon Sep 17 00:00:00 2001 From: Igor Timoshenko Date: Wed, 12 Feb 2014 16:08:44 +0000 Subject: [PATCH 07/13] Added completion script for Phing --- src/_phing | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/_phing diff --git a/src/_phing b/src/_phing new file mode 100644 index 0000000..57210da --- /dev/null +++ b/src/_phing @@ -0,0 +1,94 @@ +#compdef phing +# ------------------------------------------------------------------------------ +# Copyright (c) Igor M. Timoshenko +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is furnished +# to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# ------------------------------------------------------------------------------ +# Description +# ----------- +# +# Completion script for Phing (http://phing.info). +# +# ------------------------------------------------------------------------------ +# Authors +# ------- +# +# * Igor Timoshenko +# +# ------------------------------------------------------------------------------ + +_phing() { + local context curcontext="$curcontext" state line ret=1 + integer NORMARG + typeset -A opt_args + + # follow http://phing.info/docs/stable/webhelp/sec.commandlineargs.html for more information + _arguments \ + '(-h -help)'{-h,-help}'[display the help screen]' \ + '(-v -version)'{-v,-version}'[print version information and exit]' \ + '(-l -list)'{-l,-list}'[list all available targets in buildfile (excluding targets that have their hidden attribute set to true)]' \ + '(-q -quiet)'{-q,-quiet}'[quiet operation, no output at all]' \ + '-verbose[verbose, give some more output]' \ + '-debug[output debug information]' \ + '-logfile [use given file for log]:file:_files' \ + '-D[set the property to the specified value to be used in the buildfile]' \ + '-find []:file:_files' \ + '-buildfile [specify an alternate buildfile name. Default is build.xml]:file:_files' \ + '-logger [specify an alternate logger. Default is phing.listener.DefaultLogger. Other options include phing.listener.NoBannerLogger, phing.listener.AnsiColorLogger, phing.listener.XmlLogger, phing.listener.TargetLogger and phing.listener.HtmlColorLogger]' \ + '-propertyfile [load properties from the specified file]:file:_files' \ + '(-v --version)'{-v,--version}'[show version]' \ + '1: :->targets' \ + '*:: :->args' \ + && ret=0 + + case $state in + targets) + local buildfile; buildfile=build.xml + if [[ ! -f $buildfile ]] + then + ret=0 + else + local targets; targets=($(sed -nE "/ Date: Wed, 12 Feb 2014 16:25:53 +0000 Subject: [PATCH 08/13] Fixed typo --- src/_phing | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_phing b/src/_phing index 57210da..afdaf3e 100644 --- a/src/_phing +++ b/src/_phing @@ -38,7 +38,7 @@ _phing() { integer NORMARG typeset -A opt_args - # follow http://phing.info/docs/stable/webhelp/sec.commandlineargs.html for more information + # Follow http://phing.info/docs/stable/webhelp/sec.commandlineargs.html for more information _arguments \ '(-h -help)'{-h,-help}'[display the help screen]' \ '(-v -version)'{-v,-version}'[print version information and exit]' \ From 107bdaba20c04e979219e7c0e512ae95e3cada48 Mon Sep 17 00:00:00 2001 From: "Vadim A. Misbakh-Soloviov" Date: Sun, 23 Feb 2014 03:20:16 +0700 Subject: [PATCH 09/13] Fix _eselect completion (to latest eselect syntax changes) Signed-off-by: Vadim A. Misbakh-Soloviov --- src/_eselect | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/_eselect b/src/_eselect index 71610f7..8e57fc9 100644 --- a/src/_eselect +++ b/src/_eselect @@ -59,7 +59,7 @@ _eselect_env() { _eselect_binutils() { local binutilslist if (( $words[(I)(set)] )); then - binutilslist=(${${${(M)${(f)"$(eselect --no-color binutils list)"}## *}// \**/}//( \[*\] | \[*\] )/}) + binutilslist=(${${${(M)${(f)"$(eselect --colour=no binutils list)"}## *}// \**/}//( \[*\] | \[*\] )/}) _values 'available binutils version' $binutilslist[@] && return 0 fi _values 'binutils options' $stdopts[@] \ @@ -71,7 +71,7 @@ _eselect_binutils() { _eselect_kernel() { local kernellist if (( $words[(I)(set)] )); then - kernellist=(${${${(M)${(f)"$(eselect --no-color kernel list)"}## *}// \**/}//( \[*\] | \[*\] )/}) + kernellist=(${${${(M)${(f)"$(eselect --colour=no kernel list)"}## *}// \**/}//( \[*\] | \[*\] )/}) _values 'available kernel version' $kernellist[@] && return 0 fi _values 'kernel options' $stdopts[@] \ @@ -82,7 +82,7 @@ _eselect_kernel() { _eselect_ctags() { local ctagslist if (( $words[(I)(set)] )); then - ctagslist=(${${${(M)${(f)"$(eselect --no-color ctags list)"}## *}// \**/}//( \[*\] | \[*\] )/}) + ctagslist=(${${${(M)${(f)"$(eselect --colour=no ctags list)"}## *}// \**/}//( \[*\] | \[*\] )/}) _values 'available ctags version' $ctagslist[@] && return 0 fi _values 'ctags options' $stdopts[@] \ @@ -94,7 +94,7 @@ _eselect_ctags() { _eselect_profile() { local profilelist if (( $words[(I)(set)] )); then - profilelist=(${${${(M)${(f)"$(eselect --no-color profile list)"}## *}// \**/}//( \[*\] | \[*\] )/}) + profilelist=(${${${(M)${(f)"$(eselect --colour=no profile list)"}## *}// \**/}//( \[*\] | \[*\] )/}) _values -w 'available profiles' $profilelist[@] \ '--force[Forcibly set the symlink]' && return 0 fi @@ -106,10 +106,10 @@ _eselect_profile() { _eselect_fontconfig() { local fclistenabled fclistdisabled if (( $words[(I)(enable)] )); then - fclistdisabled=(${${${${(M)${(f)"$(eselect --no-color fontconfig list)"}## *}#*\*}// \**/}//( \[*\] | \[*\] )/}) + fclistdisabled=(${${${${(M)${(f)"$(eselect --colour=no fontconfig list)"}## *}#*\*}// \**/}//( \[*\] | \[*\] )/}) _values -w '.conf to enable' $fclistdisabled[@] && return 0 elif (( $words[(I)(disable)] )); then - fclistenabled=(${${${(M)${(M)${(f)"$(eselect --no-color fontconfig list)"}## *}#*\*}// \**/}//( \[*\] | \[*\] )/}) + fclistenabled=(${${${(M)${(M)${(f)"$(eselect --colour=no fontconfig list)"}## *}#*\*}// \**/}//( \[*\] | \[*\] )/}) _values -w '.conf to disable' $fclistenabled[@] && return 0 fi _values 'fontconfig options' $stdopts[@] \ @@ -120,7 +120,7 @@ _eselect_fontconfig() { _eselect_opengl() { local opengllist if (( $words[(I)(set)] )); then - opengllist=(${${${(M)${(f)"$(eselect --no-color opengl list)"}## *}// \**/}//( \[*\] | \[*\] )/}) + opengllist=(${${${(M)${(f)"$(eselect --colour=no opengl list)"}## *}// \**/}//( \[*\] | \[*\] )/}) _values -w 'opengl implementations and options' $opengllist[@] \ '--use-old[If an implementationis already set, use that one instead]' \ '--prefix[Set the source prefix]:path:_files -/' \ @@ -135,7 +135,7 @@ _eselect_opengl() { _eselect_vi() { local vilist if (( $words[(I)(set)] )); then - vilist=(${${${(M)${(f)"$(eselect --no-color vi list)"}## *}// \**/}//( \[*\] | \[*\] )/}) + vilist=(${${${(M)${(f)"$(eselect --colour=no vi list)"}## *}// \**/}//( \[*\] | \[*\] )/}) _values -w 'vi implementation' $vilist[@] && return 0 elif (( $words[(I)(update)] )); then _values -w 'option' '--if-unset[Do not override existing implementation]' && return 0 @@ -172,7 +172,7 @@ _eselect_news() { _values -w 'news' 'new[Count only new news items]' 'all[Count all news items]' && return 0 fi - newslist=(${${${${${${${(M)${(f)"$(eselect --no-color news list)"}## *}// \**/}/ \[/}/\] ##/\[}/%/]}/ \[/ (}/\] /) }) + newslist=(${${${${${${${(M)${(f)"$(eselect --colour=no news list)"}## *}// \**/}/ \[/}/\] ##/\[}/%/]}/ \[/ (}/\] /) }) if (( $words[(I)(read)] )); then newslist+=( "new[Read unread news items (default)]" "all[Read all news items]" "--mbox[Output in mbox format]" "--quiet[Suppress output, only change status]" "--raw[Output in raw format]" ) @@ -194,34 +194,35 @@ _eselect() { 'version[Display version information]' ) globopts=( - '--no-colour[Disable coloured output]' - '--no-color[Disable coloured output]' + '--brief[Make output shorter]' + '--colour=no[Disable colour output (default "auto")]' + '--colour=yes[Enable colour output (default "auto")]' ) - modnames=(${${${(M)${(f)"$(eselect --no-color list-modules)"}## *}// */}// /}) + modnames=(${${${(M)${(f)"$(eselect --colour=no modules list)"}## *}// */}// /}) if ((CURRENT == 2)); then _arguments -s \ "$globopts[@]" \ "*:portage:_values 'eselect modules' \$modnames[@]" && return 0 elif ((CURRENT == 3)); then - if [[ $words[2] == --no-colour || $words[2] == --no-color ]]; then + if [[ $words[2] =~ "--colour" || $words[2] =~ "--brief" ]]; then _arguments -s \ "*:portage:_values 'eselect modules' \$modnames[@]" && return 0 elif (( $modnames[(I)$words[2]] )); then if [[ "$words[2]" == (env|binutils|kernel|ctags|profile|fontconfig|opengl|vi|news) ]]; then _eselect_$words[2] "$@" else - modopts=(${${${${(M)${(f)"$(eselect --no-color $words[2] usage)"}## *}// */}// /}// */}) + modopts=(${${${${(M)${(f)"$(eselect --colour=no $words[2] usage)"}## *}// */}// /}// */}) _arguments -s \ "*:portage:_values 'eselect $words[2] options' \$modopts[@]" && return 0 fi fi elif ((CURRENT >= 4)); then - if (( $words[(I)(--no-color|--no-colour)] )); then + if (( $words[(I)(--colour=no|--colour=yes|--brief)] )); then if (( $modnames[(I)$words[3]] )); then if [[ "$words[3]" == (env|binutils|kernel|ctags|profile|fontconfig|opengl|vi|news) ]]; then _eselect_$words[3] "$@" else - modopts=(${${${${(M)${(f)"$(eselect --no-color $words[3] usage)"}## *}// */}// /}// *}) + modopts=(${${${${(M)${(f)"$(eselect --colour=no $words[3] usage)"}## *}// */}// /}// *}) _arguments -s \ "*:portage:_values 'eselect $words[3] options' \$modopts[@]" && return 0 fi From 545c7b6d6bf4577d87c69f154f4f24f6dfbe049b Mon Sep 17 00:00:00 2001 From: Foivos Date: Wed, 19 Mar 2014 04:44:48 +0200 Subject: [PATCH 10/13] Add completion for pass (password-store) This is a copy of https://github.com/zx2c4/password-store/blob/master/contrib/pass.zsh-completion --- src/_pass | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/_pass diff --git a/src/_pass b/src/_pass new file mode 100644 index 0000000..848bc67 --- /dev/null +++ b/src/_pass @@ -0,0 +1,116 @@ +#compdef pass + +# Copyright (C) 2012: +# Johan Venant +# Brian Mattern +# Jason A. Donenfeld . +# All Rights Reserved. +# This file is licensed under the GPLv2+. Please see COPYING for more information. + +_pass () { + local cmd + if (( CURRENT > 2)); then + cmd=${words[2]} + # Set the context for the subcommand. + curcontext="${curcontext%:*:*}:pass-$cmd" + # Narrow the range of words we are looking at to exclude `pass' + (( CURRENT-- )) + shift words + # Run the completion for the subcommand + case "${cmd}" in + init) + _arguments : \ + "-r[re-encrypt existing passwords]" \ + "--reencrypt[re-encrypt existing passwords]" + _pass_complete_keys + ;; + ls|list|edit) + _pass_complete_entries_with_subdirs + ;; + insert) + _arguments : \ + "-e[echo password to console]" \ + "--echo[echo password to console]" \ + "-m[multiline]" \ + "--multiline[multiline]" + _pass_complete_entries_with_subdirs + ;; + generate) + _arguments : \ + "-n[don't include symbols in password]" \ + "--no-symbols[don't include symbols in password]" \ + "-c[copy password to the clipboard]" \ + "--clip[copy password to the clipboard]" + _pass_complete_entries_with_subdirs + ;; + rm) + _arguments : \ + "-f[force deletion]" \ + "--force[force deletion]" \ + "-r[recursively delete]" \ + "--recursive[recursively delete]" + _pass_complete_entries_with_subdirs + ;; + git) + local -a subcommands + subcommands=( + "init:Initialize git repository" + "push:Push to remote repository" + "pull:Pull from remote repository" + "config:Show git config" + "log:Show git log" + "reflog:Show git reflog" + ) + _describe -t commands 'pass git' subcommands + ;; + show|*) + _pass_cmd_show + ;; + esac + else + local -a subcommands + subcommands=( + "init:Initialize new password storage" + "ls:List passwords" + "show:Decrypt and print a password" + "insert:Insert a new password" + "generate:Generate a new password using pwgen" + "edit:Edit a password with \$EDITOR" + "rm:Remove the password" + "git:Call git on the password store" + "version:Output version information" + "help:Output help message" + ) + _describe -t commands 'pass' subcommands + _arguments : \ + "--version[Output version information]" \ + "--help[Output help message]" + _pass_cmd_show + fi +} + +_pass_cmd_show () { + _arguments : \ + "-c[put it on the clipboard]" \ + "--clip[put it on the clipboard]" + _pass_complete_entries +} +_pass_complete_entries_helper () { + local IFS=$'\n' + local prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" + _values -C 'passwords' $(find "$prefix" \( -name .git -o -name .gpg-id \) -prune -o $@ -print | sed -e "s#${prefix}.##" -e 's#\.gpg##' | sort) +} + +_pass_complete_entries_with_subdirs () { + _pass_complete_entries_helper +} + +_pass_complete_entries () { + _pass_complete_entries_helper -type f +} + +_pass_complete_keys () { + local IFS=$'\n' + # Extract names and email addresses from gpg --list-keys + _values 'gpg keys' $(gpg2 --list-secret-keys --with-colons | cut -d : -f 10 | sort -u | sed '/^$/d') +} From 48d1cb8e9cdb580b5a8e87ecb4f333cf85b1aa5b Mon Sep 17 00:00:00 2001 From: Werner Beroux Date: Sat, 22 Mar 2014 14:25:56 +0100 Subject: [PATCH 11/13] Add VBoxManager modifyhd auto-complete. --- src/_virtualbox | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/_virtualbox b/src/_virtualbox index 646711a..de0e35a 100644 --- a/src/_virtualbox +++ b/src/_virtualbox @@ -193,6 +193,16 @@ _vboxmanage() { :machine:_vboxmachines \ :modifyvm_option:_vboxopts_modifyvm ;; + modifyhd) + _arguments \ + :filename:_files \ + '--type:hd type:(normal writethrough immutable shareable readonly multiattach)' \ + '--autoreset:on off:(on off)' \ + '--property: :' \ + '--compact' \ + '--resize:megabytes:' \ + '--resizebyte:bytes:' + ;; import) _arguments \ ':ovf file:_files -g \*.{ovf,ova}' \ From deb6a6fa4eb6f85ce22ab0657eb5d9973d8b9a9e Mon Sep 17 00:00:00 2001 From: lucapette Date: Sat, 29 Mar 2014 18:43:38 +0100 Subject: [PATCH 12/13] Fix typo in _jekyll completion As per subject --- src/_jekyll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_jekyll b/src/_jekyll index 37f3576..6326ac9 100644 --- a/src/_jekyll +++ b/src/_jekyll @@ -42,7 +42,7 @@ case $state in "help:Dislplay global or [command] help documentation" "import:Import your old blog to Jekyll" "new:Creates a new Jekyll site scaffold in PATH" - "serve:Serve your stie locally" + "serve:Serve your site locally" ) _describe -t subcommands 'jekyll subcommand' subcommands && ret=0 From 6b0f09ddb22440a02758a88dbab18f810d55fa41 Mon Sep 17 00:00:00 2001 From: Joe Bloggs Date: Fri, 14 Mar 2014 21:48:06 +0000 Subject: [PATCH 13/13] Completion for ps command, for iw and a how-to guide for creating completion files --- src/_iw | 247 +++++++++++++++++++++ src/_ps | 102 +++++++++ zsh-completions-howto.org | 440 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 789 insertions(+) create mode 100644 src/_iw create mode 100644 src/_ps create mode 100644 zsh-completions-howto.org diff --git a/src/_iw b/src/_iw new file mode 100644 index 0000000..3cc3c59 --- /dev/null +++ b/src/_iw @@ -0,0 +1,247 @@ +#compdef iw + +# Some parameters to hold patterns that will be used later. +local xp='[[:xdigit:]][[:xdigit:]]' +local -a bssid devices flags fouraddr fouronoff frequency high_throughput ifacename ifacetype ifacetypes +local -a matchany matchnum key lladdr lladdrs meshid meshidval ssid value +# matches any word +matchany=(/$'[^\0]##\0'/) +# matches any number +matchnum=(/$'[[:digit:]]##\0'/) +# matches any BSSID +bssid=($matchany ':bssid:BSSID:') +# matches any devices +devices=( /$'[[:alpha:]]##[[:digit:]]##(\.[[:digit:]]##)#\0'/ ':interfaces:network_interface:_net_interfaces' ) +# matches the word 'flags' followed by a list of some of the following words: none fcsfail control otherbss cook +flags=(/$'flags\0'/ ':flags:flags:(flags)' $matchany ':flags:flags:(none fcsfail control otherbss cook)' \#) +# matches the word '4addr' followed by either 'on' or 'off' +fouronoff=(/$'(on|off)\0'/ ':4addr:4addr:(on off)') +fouraddr=( /$'4addr\0'/ ':4addr:4addr:(4addr)' $fouronoff ) +# matches any number (description is 'frequency') +frequency=($matchnum ':freq:frequency:') +# matches one of HT20 HT40+ or HT40- +high_throughput=(/$'HT[0-9]##(+|-)#\0'/ ':HT:high throughput:(HT20 HT40+ HT40-)') +# matches any name (description is 'name') +ifacename=($matchany ':name:name:') +# matches the word 'type' followed by one of: managed ibss monitor mesh wds +ifacetypes=(/$'(managed|ibss|monitor|mesh|wds)\0'/ ':type:type:(managed ibss monitor mesh wds)') +ifacetype=(/$'type\0'/ ':type:type:(type)' $ifacetypes) +# matches any word (description is 'key') +key=($matchany ':key:key:') +# matches a MAC address (i.e. a sequence of six 2-digit numbers separated by spaces), $xp is defined earlier. +lladdr=(/"${xp}:${xp}:${xp}:${xp}:${xp}:${xp}"$'\0'/ ':lladdress:link layer (MAC) address:') +# as above but with a different description +lladdrs=(/"${xp}:${xp}:${xp}:${xp}:${xp}:${xp}"$'\0'/ ':lladdress:link layer (MAC) addresses (use - to match any octet):' \#) +# matches the word 'mesh_id' followed by a number +meshidval=($matchnum ':meshid:mesh ID:') +meshid=(/$'mesh_id\0'/ ':meshid:meshid:(mesh_id)' $meshidval) +# matches any word (description 'SSID') +ssid=($matchany ':ssid:SSID:') +# matches any word (description 'value') +value=($matchany ':val:value:') +# matches any number (description 'value') +numvalue=($matchnum ':val:value:') + +# Use the _regex_words function to create a variable containing command words to go after "iw reg" +local -a reg_cmds +_regex_words regulatory-commands "reg command" \ + 'g*et:print out the kernels current regulatory domain information'\ + 's*et:notify the kernel about the current regulatory domain' +reg_cmds=("$reply[@]") + +# Options for to go after "iw event" +local -a event_opts +_regex_words event-options "event option" \ + '-t:print timestamp' \ + '-r:print relative timstamp' \ + '-f:print full frame for auth/assoc etc' +event_opts=("$reply[@]") + +# Commands to go after "iw phy wowlan enable" +local -a phy_wowlan_enable_cmds +_regex_words phy-wowlan-enable-commands "phy WoWLAN enable commands" \ + '4*way-handshake:enable WoWLAN with 4way handshake trigger' \ + 'a*ny:enable WoWLAN with any trigger' \ + 'd*isconnect:enable WoWLAN with disconnect trigger' \ + 'e*ap-identity-request:enable WoWLAN with EAP identity request trigger' \ + 'g*tk-rekey-failure:enable WoWLAN with gtk rekey failure trigger' \ + 'm*agic-packet:enable WoWLAN with magic packet trigger' \ + 'p*atterns:MAC address triggers:$lladdrs' \ + 'r*fkill-release:enable WoWLAN with rfkill release trigger' +phy_wowlan_enable_cmds=("$reply[@]") + +# Commands to go after "iw phy wowlan" +local -a phy_wowlan_cmds +_regex_words phy-wowlan-commands "phy WoWLAN commands" \ + 's*how:show WoWLAN status' \ + 'd*isable:disable WoWLAN' \ + 'e*nable:enable WoWLAN:$phy_wowlan_enable_cmds' +phy_wowlan_cmds=("$reply[@]") + +# Some parameters to hold patterns that will be used for "iw phy set" commands +# (not perfect, but mostly OK). +local -a phy_set_antenna phy_set_channel phy_set_coverage phy_set_frag phy_set_freq phy_set_distance +local -a phy_set_name phy_set_netns phy_set_rts phy_set_txpower phy_txpower_opt +phy_set_antenna=($matchany ':antenna:bitmap:') +phy_set_channel=($matchnum ':channel:channel (1-14):' $high_throughput) +phy_set_coverage=($matchnum ':coverage:coverage class (0-255):') +phy_set_distance=($matchnum ':distance:valid values\: 0 - 114750:') +phy_set_frag=(/$'([0-9]##|off)\0'/ ':channel:channel (1-14):(1 2 3 4 5 6 7 8 9 10 11 12 13 14 off)') +phy_set_freq=($frequency $high_throughput) +phy_set_name=($matchany ':name:device name:') +phy_set_netns=($matchany ':netns:network namespace:') +phy_set_rts=($matchnum ':rts:rts threshold:') +phy_txpower_opt=($matchany ':txpower:tx power in mBm:') +_regex_words phy-set-txpower "set txpower" \ + 'a*uto:auto:' \ + 'f*ixed:fixed:$phy_txpower_opt' \ + 'l*imit:limit:$phy_txpower_opt' +phy_set_txpower=("$reply[@]") + +# Commands to go after "iw phy set" +local -a phy_set_cmds +_regex_words phy-set-commands "phy set commands" \ + 'a*ntenna:set a bitmap of allowed antennas to use for TX and RX:$phy_set_antenna' \ + 'ch*annel:set channel:$phy_set_channel' \ + 'co*verage:set coverage class (1 for every 3 usec of air propagation time):$phy_set_coverage' \ + 'd*istance:set appropriate coverage class for given link distance in meters:$phy_set_distance' \ + 'fra*g:set fragmentation threshold:$phy_set_frag' \ + 'fre*q:set frequency/channel the hardware is using, including HT configuration:$phy_set_freq' \ + 'na*me:rename this wireless device:$phy_set_name' \ + 'ne*tns:set network namespace:$phy_set_netns' \ + 'r*ts:set rts threshold:$phy_set_rts' \ + 't*xpower:specify transmit power level and setting type:$phy_set_txpower' +phy_set_cmds=("$reply[@]") + +# Commands to go after "iw phy interface" +local -a phy_interface_cmds +# This needs work (should not offer meshid, fouraddr of flags more than once, and need to accomodate multiple flag options) +phy_interface_cmds=(\( /$'add\0'/ ':add:add a new virtual interface with the given configuration:(add)' $ifacename $ifacetype \ + \( $meshid \| $fouraddr \| $flags \) \# \)) + +# Commands to go after "iw phy " +local -a phy_cmds +_regex_words phy-commands "phy command" \ + 's*et:set/configure interface properties:$phy_set_cmds' \ + 'inf*o:show capabilities for the specified wireless device' \ + 'int*erface:add a new virtual interface with the given configuration:$phy_interface_cmds' \ + 'w*owlan:WoWLAN commands:$phy_wowlan_cmds' +phy_cmds=("$reply[@]") + +# Parameters to hold patterns for dev commands +local -a dev_cmds_connect dev_cmds_cqm dev_cmds_get dev_cmds_ibss dev_cmds_interface dev_cmds_mesh dev_cmds_scan_options +local -a dev_cmds_mpath dev_cmds_offchannel dev_cmds_roc dev_cmds_scan dev_cmds_set dev_cmds_station dev_cmds_survey +dev_cmds_connect=($ssid $frequency $bssid $key) +dev_cmds_cqm=(/$'rssi\0'/ ':rssi:rssi:(rssi)' $matchnum ':thresh:threshold:' $matchnum ':hysteresis:hysteresis:') +dev_cmds_get=(/$'(mesh_param|power_save)\0'/ ':get:parameter:(mesh_param power_save)' $value) +# TODO: THIS NEEDS WORK! THE FINAL OPTIONS FOR JOIN NEED WORK +# dev ibss join [fixed-freq] [] [beacon-interval ] [basic-rates ] [mcast-rate ] [key d:0:abcde] +dev_cmds_ibss=(\( /$'leave\0'/ ':cmd:command:((leave:"Leave the IBSS cell"))' \| \( /$'join\0'/ ':cmd:command:((join\:"Join an IBSS cell"))' $ssid $frequency \( /$'fixed-freq\0'/ ':opt:option:((fixed-freq\:"fixed frequency (no args)"))' \| $bssid \| /$'beacon-interval\0'/ ':opt:option:((beacon-interval\:"beacon interval (takes single arg)"))' $numvalue \| /$'basic-rates\0'/ ':opt:option:((basic-rates\:"basic rates (comma separated list of rates)"))' $numvalue \| /$'mcast-rate\0'/ ':opt:option:((mcast-rate\:"multicast rate (takes single arg)"))' $numvalue \| $key \) \# \) \)) +dev_cmds_interface=(/$'add\0'/ ':add:add:(add)' $ifacename $ifacetype \( $meshid \| $fouraddr \| $flags \) \# ) +dev_cmds_mesh=(\( /$'leave\0'/ ':leave:leave a mesh:(leave)' \| /$'join\0'/ ':join:join a mesh:(join)' \ + $matchnum ':meshid:mesh ID:' $matchany ':parameter:mesh parameters [=]*:' \# \)) +dev_cmds_mpath=(\( /$'(del|get)\0'/ ':mpath:mesh path command:((del\:"remove the mesh path to the given node" \ +get\:"get information on mesh path to the given node"))' $lladdr \| /$'(new|set)\0'/ ':mpath:mesh path \ +command:((new\:"create a new mesh path (instead of relying on automatic discovery)" set\:"set an existing mesh \ +paths next hop"))' $lladdr /$'next_hop\0'/ ':nexthop:next hop:(next_hop)' $lladdr \| /$'dump\0'/ ':mpath:mesh path \ +command:((dump\:"list known mesh paths"))' \)) +dev_cmds_offchannel=($frequency $matchnum ':duration:duration:') +dev_cmds_roc=(/$'start\0'/ ':start:start:(start)' $frequency $matchnum ':time:time:') +dev_cmds_scan_options=(/$'freq\0'/ ':freq:freq:(freq)' $frequency $frequency \# /$'ies\0'/ ':ies:ies:(ies)' $lladdr \( /$'ssid\0'/ ':ssid:ssid:(ssid)' $ssid \# \| /$'passive\0'/ ':opt:passive:(passive)' \)) +dev_cmds_scan=(\( $dev_cmds_scan_options \| $matchany -'! [[ $match[1] =~ "dump|trigger" ]]' ':opt:option:((-u\:"include unknown data in results" \:""))' $dev_cmds_scan_options \| /$'dump\0'/ ':cmd:command:((dump\:"dump the current scan results"))' $matchany ':opt:option:((-u\:"include unknown data in results" \:""))' \| /$'trigger\0'/ ':cmd:command:((trigger\:"trigger a scan on the given frequencies with probing for the given SSIDs (or wildcard if not given) unless passive scanning is requested"))' $dev_cmds_scan_options \)) +local -a dev_cmds_set_bitrates dev_cmds_set_freq dev_cmds_set_mesh_param +local -a dev_cmds_set_monitor dev_cmds_set_peer dev_cmds_set_power_save +local -a dev_cmds_set_type dev_cmds_set_txpower +# dev set bitrates [legacy-<2.4|5> *] +dev_cmds_set_bitrates=(/$'legacy-*\0'/ ':opt:legacy:(legacy-2.4 legacy-2.5)' $matchnum ':rate:legacy rate in Mbps:') +# dev set freq [HT20|HT40+|HT40-] +dev_cmds_set_freq=($frequency $high_throughput) +# dev set mesh_param = [=]* +dev_cmds_set_mesh_param=( $matchany ':val:param=value:' \# ) +# dev set monitor * +dev_cmds_set_monitor=( $matchany ':flag:flag:((none\:"no special flags" fcsfail\:"show frames with FCS errors"\ + control\:"show control frames" otherbss\:"show frames from other BSSes" cook\:"use cooked mode"))' \# ) +# dev set peer +dev_cmds_set_peer=($lladdr) +# dev set power_save +dev_cmds_set_power_save=(/$'(on|off)\0'/ ':opt:power save mode:(on off)') + +_regex_words setcmds "dev set commands" \ + '4*addr:set interface 4addr (WDS) mode:$fouronoff'\ + 'b*itrates:set/clear specified rate masks:$dev_cmds_set_bitrates'\ + 'c*hannel:set channel:$phy_set_channel'\ + 'f*req:set frequency:$dev_cmds_set_freq'\ + 'mesh_param:set mesh parameters:$dev_cmds_set_mesh_param'\ + 'meshid:set mesh id:$meshidval'\ + 'mo*nitor:set monitor flags:$dev_cmds_set_monitor'\ + 'pe*er:set interface WDS peer MAC address:$dev_cmds_set_peer'\ + 'po*wer_save:set power save on/off:$dev_cmds_set_power_save'\ + 'tx*power:set transmission power:$phy_set_txpower'\ + 'ty*pe:set type:$ifacetypes' +dev_cmds_set=("$reply[@]") + +local -a dev_cmds_station_plink dev_cmds_station_vlan +dev_cmds_station_plink=(/$'(open|block)\0'/ ':opt::(open block)') +dev_cmds_station_vlan=($matchnum ':val:ifindex:') + +local -a dev_cmds_station_set +_regex_words stationsetcmds "dev station set commands"\ + 'plink_action:set peer link action:$dev_cmds_station_plink'\ + 'vlan:set AP VLAN:$dev_cmds_station_vlan' +dev_cmds_station_set=(\( $lladdr \) "$reply[@]") + +_regex_words stationcmds "dev station commands" \ + 'del:remove the given station entry (use with caution!):$lladdr'\ + 'dump:list all stations known, e.g. the AP on managed interfaces:'\ + 'get:get information for a specific station:$lladdr'\ + 'set:set AP VLAN or mesh peer link action:$dev_cmds_station_set' +dev_cmds_station=("$reply[@]") + +dev_cmds_survey=(/$'dump\0'/ ':dump:list all gathered channel survey data:(dump)') + +local -a dev_cmds +_regex_words dev-commands "dev commands" \ + 'co*nnect:join a network:$dev_cmds_connect' \ + 'cq*m:set connection quality monitor RSSI threshold:$dev_cmds_cqm' \ + 'de*l:remove this virtual interface' \ + 'di*sconnect:disconnect from the current network' \ + 'g*et:retrieve mesh parameter / power save state:$dev_cmds_get' \ + 'ib*ss:join/leave IBSS cell:$dev_cmds_ibss' \ + 'inf*o:show information for this interface' \ + 'int*erface:add an interface:$dev_cmds_interface' \ + 'l*ink:print information about the current link, if any' \ + 'me*sh:join/leave a mesh:$dev_cmds_mesh' \ + 'mp*ath:mesh path commands:$dev_cmds_mpath' \ + 'o*ffchannel:leave operating channel and go to the given channel for a while:$dev_cmds_offchannel' \ + 'r*oc:roc:$dev_cmds_roc' \ + 'sc*an:scan:$dev_cmds_scan' \ + 'se*t:set interface parameter:$dev_cmds_set' \ + 'st*ation:station commands:$dev_cmds_station' \ + 'su*rvey:list all gathered channel survey data:$dev_cmds_survey' +dev_cmds=( $devices "$reply[@]") + +# Arguments to _regex_arguments, built up in array $args. +local -a args reply +# Command word. Don't care what that is. +args=( $matchany ) + +local -a phydevs +phy_devs=( \( $(iw list|grep '^[[:alnum:]]\+'|cut -f 2 -d ' ') \) ) +phy_cmds=( \( $matchany ":test:test:$phy_devs[*]" \) "$phy_cmds[@]" ) + +_regex_words commands "iw command" \ + 'd*ev:commands to control/list the software devices:$dev_cmds' \ + 'e*vent:monitor events from the kernel:$event_opts' \ + 'h*elp:print usage for each command' \ + 'l*ist:list all wireless devices and their capabilities' \ + 'p*hy:commands to control the physical device:$phy_cmds' \ + 'r*eg:get/set regulatory domain:$reg_cmds' +args+=("$reply[@]") + +_regex_arguments _iw "${args[@]}" + +_iw "$@" + +# Local Variables: +# mode:shell-script +# End: diff --git a/src/_ps b/src/_ps new file mode 100644 index 0000000..a0755d4 --- /dev/null +++ b/src/_ps @@ -0,0 +1,102 @@ +#compdef ps + +# This works with procps version 3.2.8 + +local context state state_descr line +typeset -A opt_args +local filterexcl="(-A -a -C -d -e -g -G --group --Group -p --pid --ppid -s --sid -t --tty -u -U --user --User)" + +_arguments -s -w \ + "$filterexcl-A[all processes]"\ + "$filterexcl-a[all w/ tty except session leaders]"\ + "--cumulative[include some dead child process data (as a sum with the parent)]"\ + "(-f -F --format -l -o -O)--context[display security context format (for SE Linux)]"\ + "-c[show different scheduler information]"\ + "$filterexcl-C[by command name]:processes:->pname"\ + "(--columns)--cols[set screen width]:width:( )"\ + "(--cols)--columns[set screen width]:width:( )"\ + "--deselect[negate selection]"\ + "$filterexcl-d[all except session leaders]"\ + "$filterexcl-e[all processes]"\ + "--forest[ASCII art process tree]"\ + "(--context -F --format -o -O)-f[full format listing]"\ + "(--context -f --format -o -O)-F[extra full format]"\ + "(--context -f -F -j -l -o -O)--format[user-defined format]:output format:->format"\ + "$filterexcl-g[by session OR by effective group name]:groups:_groups"\ + "$filterexcl-G[by real group ID (supports names)]:groups:->rgid"\ + "$filterexcl--group[by session OR by effective group name]:groups:_groups"\ + "$filterexcl--Group[by real group ID (supports names)]:groups:->rgid"\ + "-H[show process hierarchy]"\ + "(--no-heading)--heading[repeat header lines, one per page of output]"\ + "-j[jobs format]"\ + "-l[long format. the -y option is often useful with this]"\ + "-L[show threads, possibly with LWP and NLWP columns]"\ + "-m[show threads after processes]"\ + "-M[add a column of security data]"\ + "-N[negate selection]"\ + "(--heading --header)--no-heading[omit header lines]"\ + "(--context -f -F --format -j -l)-o[user-defined format]:output format:->format"\ + "(--context -f -F --format -j -l)-O[preloaded -o (user-defined with some)]:output format:->format"\ + "$filterexcl-p[by process ID]:process IDs:->pid"\ + "$filterexcl--pid[by process ID]:process IDs:->pid"\ + "$filterexcl--ppid[select by parent process ID]:process IDs:->ppid"\ + "--rows[set screen height.]:height:( )"\ + "$filterexcl-s[by session IDs]:sessions:->sid"\ + "$filterexcl--sid[by session IDs]:sessions:->sid"\ + "--sort[specify sorting order]:sort specs:->sortspec"\ + "$filterexcl-t[by tty]:ttys:->tty"\ + "-T[show threads, possibly with SPID column]"\ + "$filterexcl--tty[by tty]:ttys:->tty"\ + "$filterexcl-u[by effective user ID (supports names)]:users:_users"\ + "$filterexcl-U[by real user ID (supports names)]:users:_users"\ + "$filterexcl--user[by effective user ID (supports names)]:users:_users"\ + "$filterexcl--User[by real user ID (supports names)]:users:_users"\ + "(--version)-V[print the procps version]"\ + "(-V)--version[print the procps version]"\ + "-w[wide output]"\ + "-y[use with -l, do not show flags, show rss in place of addr]"\ + "1:BSD-style options (complete - to see unix & gnu-style options):((T\:'all processes on this terminal' a\:'all w/ tty, including other users' r\:'only running processes' x\:'processes w/o controlling ttys' t\:'list by tty' j\:'BSD jobs control format' l\:'BSD long format' s\:'signal format' v\:'virtual memory format' u\:'user-oriented format' X\:'register format' L\:'list format codes' S\:'sum info of children into parents' c\:'true command name' n\:'numeric WCHAN & UID' H\:'show threads as if they were processes' U\:'by effective user ID' p\:'by process ID'))"\ + - debug "--info[print debugging info]" + +case "$state" in + pid) + _values -s , 'process id' "${(uonzf)$(ps -A o pid=)}" + ;; + rgid) + _values -s , 'process group id' "${(uonzf)$(ps -A o rgid=)}" + ;; + pname) + local ispat="pattern matching " + if (( ${+opt_args[-x]} )) + then + ispat="" + fi + if (( ${+opt_args[-f]} )) + then + _wanted pname expl $ispat'process command line' compadd ${(u)${(f)"$(ps -A o cmd=)"}} + else + _wanted pname expl $ispat'process name' compadd ${(u)${(f)"$(ps -A co cmd=)"}} + fi + ;; + sid) + _values -s , 'session id' "${(uonzf)$(ps -A o sid=)}" + ;; + tty) + local -a ttys + ttys=( /dev/tty*(N) /dev/pts/*(N) ) + _values -s , 'terminal device' ${ttys#/dev/} + ;; + ppid) + _values -s , 'parent process id' "${(uonzf)$(ps -A o ppid=)}" + ;; + sortspec) + _values -s , 'format specifier (prefix with - for decreasing order)' "${(uozf)$(ps L|cut -f 1 -d" ")}" + ;; + format) + _values -s , 'format specifier' "${(uozf)$(ps L|cut -f 1 -d" ")}" + ;; +esac + +# Local Variables: +# mode:shell-script +# End: diff --git a/zsh-completions-howto.org b/zsh-completions-howto.org new file mode 100644 index 0000000..d494a10 --- /dev/null +++ b/zsh-completions-howto.org @@ -0,0 +1,440 @@ +* Intro +The official documentation for writing zsh completion functions is difficult to understand, and doesn't give many examples. +At the time of writing this document I was able to find a few other tutorials on the web, however those tutorials only +explain a small portion of the capabilities of the completion system. This document aims to cover areas not explained elsewhere, +with examples, so that you can learn how to write more advanced completion functions. I do not go into all the details, but will +give enough information and examples to get you up and running. If you need more details you can look it up for yourself in the + [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][official documentation]]. + +Please make any scripts that you create publically available for others (e.g. by forking this repo and making a [[id:64bcd501-b0f0-48c7-b8e2-07af708b95ec][pull request]]). +Also if you have any more information to add or improvements to make to this tutorial, please do. +* Getting started +** Telling zsh which function to use for completing a command +Completion functions for commands are stored in files with names beginning with an underscore _, and these files should +be placed in a directory listed in the $fpath variable. +You can add a directory to $fpath by adding a line like this to your ~/.zshrc file: +#+BEGIN_SRC sh +fpath=(~/newdir $fpath) +#+END_SRC +The first line of a completion function file can look something like this: +#+BEGIN_SRC sh +#compdef foobar +#+END_SRC +This tells zsh that the file contains code for completing the foobar command. +This is the format that you will use most often for the first line, but you can also use the same file for completing +several different functions if you want. See [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Autoloaded-files][here]] for more details. + +You can also use the compdef command directly (e.g. in your ~/.zshrc file) to tell zsh which function to use for completing +a command like this: +#+BEGIN_SRC sh +> compdef _function foobar +#+END_SRC +or to use the same completions for several commands: +#+BEGIN_SRC sh +> compdef _function foobar goocar hoodar +#+END_SRC +or if you want to supply arguments: +#+BEGIN_SRC sh +> compdef '_function arg1 arg2' foobar +#+END_SRC +See [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Functions-4][here]] for more details. +** Completing generic gnu commands +Many [[http://www.gnu.org/][gnu]] commands have a standardized way of listing option descriptions (when the --help option is used). +For these commands you can use the _gnu_generic function for automatically creating completions, like this: +#+BEGIN_SRC sh +> compdef _gnu_generic foobar +#+END_SRC +or to use _gnu_generic with several different commands: +#+BEGIN_SRC sh +> compdef _gnu_generic foobar goocar hoodar +#+END_SRC +This line can be placed in your ~/.zshrc file. +** Copying completions from another command +If you want a command, say cmd1, to have the same completions as another, say cmd2, which has already had +completions defined for it, you can do this: +#+BEGIN_SRC sh +> compdef cmd1=cmd2 +#+END_SRC +This can be useful for example if you have created an alias for a command to help you remember it. +* Writing your own completion functions +A good way to get started is to look at some already defined completion functions. +On my linux installation these are found in /usr/share/zsh/functions/Completion/Unix +and /usr/share/zsh/functions/Completion/Linux and a few other subdirs. + +You will notice that the _arguments function is used a lot in these files. +This is a utility function that makes it easy to write simple completion functions. +The _arguments function is a wrapper around the compadd builtin function. +The compadd builtin is the core function used to add completion words to the command line, and control its behaviour. +However, most of the time you will not need to use compadd, since there are many utility functions such as _arguments +and _describe which are easier to use. + +For very basic completions the _describe function should be adequate + +** Utility functions +Here is a list of some of the utility functions that may be of use. +The full list of utility functions, with full explanations, is available [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions][here]]. +Examples of how to use these functions are given in the next section. + +*** main utility functions for overall completion +| _alternative | Can be used to generate completion candidates from other utility functions or shell code. | +| _arguments | Used to specify how to complete individual options & arguments for a command with unix style options. | +| _describe | Used for creating simple completions consisting of single words with descriptions (but no actions). Easier to use than _arguments | +| _gnu_generic | Can be used to complete options for commands that understand the `--help' option. | +| _regex_arguments | Creates a function for matching commandline arguments with regular expressions, and then performing actions/completions. | +*** functions for performing complex completions of single words +| _values | Used for completing arbitrary keywords (values) and their arguments, or comma separated lists of such combinations. | +| _combination | Used to complete combinations of values, for example pairs of hostnames and usernames. | +| _multi_parts | Used for completing multiple parts of words separately where each part is separated by some char, e.g. for completing partial filepaths: /u/i/sy -> /usr/include/sys | +| _sep_parts | Like _multi_parts but allows different separators at different parts of the completion. | +*** functions for completing specific types of objects +| _path_files | Used to complete filepaths. Take several options to control behaviour. | +| _files | Calls _path_files with all options except -g and -/. These options depend on file-patterns style setting. | +| _net_interfaces | Used for completing network interface names | +| _users | Used for completing user names | +| _groups | Used for completing group names | +| _options | Used for completing the names of shell options. | +| _parameters | Used for completing the names of shell parameters/variables (can restrict to those matching a pattern). | +*** functions for handling cached completions +If you have a very large number of completions you can save them in a cache file so that the completions load quickly. +| _cache_invalid | indicates whether the completions cache corresponding to a given cache identifier needs rebuilding | +| _retrieve_cache | retrieves completion information from a cache file | +| _store_cache | store completions corresponding to a given cache identifier in a cache file | +*** other functions +| _message | Used for displaying help messages in places where no completions can be generated. | +| _regex_words | Can be used to generate arguments for the _regex_arguments command. This is easier than writing the arguments manually. | +| _guard | Can be used in the ACTION of specifications for _arguments and similar functions to check the word being completed. | +*** Actions +Many of the utility functions such as _arguments, _regex_arguments, _alternative and _values may include an action +at the end of an option/argument specification. This action indicates how to complete the corresponding argument. +The actions can take one of the following forms: +| ( ) | Argument is required but no matches are generated for it. | +| (ITEM1 ITEM2) | List of possible matches | +| ((ITEM1\:'DESC1' ITEM2\:'DESC2')) | List of possible matches, with descriptions. Make sure to use different quotes than those around the whole specification. | +| ->STRING | Set $state to STRING and continue ($state can be checked in a case statement after the utility function call) | +| FUNCTION | Name of a function to call for generating matches or performing some other action, e.g. _files or _message | +| {EVAL-STRING} | Evaluate string as shell code to generate matches. This can be used to call a utility function with arguments, e.g. _values or _describe | +| =ACTION | Inserts a dummy word into completion command line without changing the point at which completion takes place. | +Not all action types are available for all utility functions that use them. For example the ->STRING type is not available in the +_regex_arguments or _alternative functions. +** Writing simple completion functions using _describe +The _describe function can be used for simple completions where the order and position of the options/arguments is +not important. You just need to create an array parameter to hold the options & their descriptions, and then pass +the parameter name as an argument to _describe. The following example creates completion candidates -c and -d, with +the descriptions (note this should be put in a file called _cmd in some directory listed in $fpath). +#+BEGIN_SRC sh +#compdef cmd +local -a options +options=('-c:description for -c opt' '-d:description for -d opt') +_describe 'values' options +#+END_SRC + +You can use several different lists separated by a double hyphen e.g. like this: +#+BEGIN_SRC sh +local -a options arguments +options=('-c:description for -c opt' '-d:description for -d opt') +arguments=('e:description for e arg' 'f:description for f arg') +_describe 'values' options -- arguments +#+END_SRC + +The _describe function can be used in an ACTION as part of a specification for _alternative, _arguments or _regex_arguments. +In this case you will have to put it in braces with its arguments, e.g. 'TAG:DESCRIPTION:{_describe 'values' options}' +** Writing completion functions using _alternative +Like _describe, this function performs simple completions where the order and position of options/arguments is not important. +However, unlike _describe, you can call execute shell code or call functions to obtain the completion candidates. + +As arguments it takes a list of specifications each in the form 'TAG:DESCRIPTION:ACTION' where TAG is a tag name, +DESCRIPTION is a description, and ACTION is one of the action types listed previously (apart from the ->STRING and =ACTION forms). +For example: +#+BEGIN_SRC sh +_alternative 'args:custom args:(a b c)' 'files:filenames:_files' +#+END_SRC +The first specification adds completion candidates a, b & c, and the second specification calls the _files function +for completing filepaths. + +We could split the specifications over several lines with \ and add descriptions to each of the custom args like this: +#+BEGIN_SRC sh +_alternative 'args:custom args:((a\:"description a" b\:"description b" c\:"description c"))'\ + 'files:filenames:_files' +#+END_SRC + +If we want to call _files with arguments we can put it in braces, like this: +#+BEGIN_SRC sh +_alternative 'args:custom args:((a\:"description a" b\:"description b" c\:"description c"))'\ + 'files:filenames:{_files -/}' +#+END_SRC + +To use parameter expansion to create our list of completions we must use double quotes to quote the specifications, +e.g: +#+BEGIN_SRC sh +_alternative "dirs:user directories:($userdirs)"\ + "pids:process IDs:($(ps -A o pid=))" +#+END_SRC +In this case the first specification adds the words stored in the $userdirs variable, and the second specification +evaluates 'ps -A o pid=' to get a list of pids to use as completion candidates. + +We can use other utility functions such as _values in the ACTION to perform more complex completions, e.g: +#+BEGIN_SRC sh +_alternative "dirs:user directories:($userdirs)"\ + 'opts:comma separated opts:{_values -s , a b c}' +#+END_SRC +this will complete the items in $userdirs, aswell as a comma separated list containing a, b &/or c. + +As with _describe, the _alternative function can itself be used in an ACTION as part of a specification for _arguments +or _regex_arguments. +** Writing completion functions using _arguments +With the _arguments function you can create more sophisticated completion functions. +Like the _alternative function, _arguments takes a list of specification strings as arguments. +These specification strings can be for specifying options and any corresponding option arguments (e.g. -f filename), +or command arguments. + +Basic option specifications take the form '-OPT[DESCRIPTION]', e.g. like this: +#+BEGIN_SRC sh +_arguments '-s[sort output]' '--l[long output]' '-l[long output]' +#+END_SRC +Arguments for the option can be specified after the option description in this form '-OPT[DESCRIPTION]:MESSAGE:ACTION', +where MESSAGE is a message to display and ACTION can be any of the forms mentioned in the ACTIONS section above. +For example: +#+BEGIN_SRC sh +_arguments '-f[input file]:filename:_files' +#+END_SRC + +Command argument specifications take the form 'N:MESSAGE:ACTION' where N indicates that it is the Nth command argument, +and MESSAGE & ACTION are as before. If the N is omitted then it just means the next command argument (after any that have +already been specified). If a double colon is used at the start (after N) then the argument is optional. +For example: +#+BEGIN_SRC sh +_arguments '-s[sort output]' '1:first arg:_net_interfaces' '::optional arg:_files' ':next arg:(a b c)' +#+END_SRC +here the first arg is a network interface, the next optional arg is a file name, the last arg can be either a, b or c, +and the -s option may be completed at any position. + +The _arguments function allows the full set of ACTION forms listed in the ACTION section above. +This means that you can use actions for selecting case statement branches like this: +#+BEGIN_SRC sh +_arguments '-m[music file]:filename:->files' '-f[flags]:flag:->flags' +case "$state" in + files) + local -a music_files + music_files=( Music/**/*.{mp3,wav,flac,ogg} ) + _multi_parts / music_files + ;; + flags) + _values -s , 'flags' a b c d e + ;; +esac +#+END_SRC +In this case paths to music files are completed stepwise descending down directories using the _multi_parts function, +and the flags are completed as a comma separated list using the _values function. + +I have just given you the basics of _arguments specifications here, you can also specify mutually exclusive options, +repeated options & arguments, options beginning with + insead of -, etc. For more details see the [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][official documentation]]. +Also have a look at the tutorials mentioned at the end of this document, and the completion functions in the [[https://github.com/vapniks/zsh-completions/tree/master/src][src directory]]. +** Writing completion functions using _regex_arguments and _regex_words +If you have a complex command line specification with several different possible argument sequences then +the _regex_arguments function may be what you need. + +_regex_arguments creates a completion function whose name is given by the first argument. +Hence you need to first call _regex_arguments to create the completion function, and then call that function, +e.g. like this: +#+BEGIN_SRC sh +_regex_arguments _cmd OTHER_ARGS.. +_cmd "$@" +#+END_SRC + +The OTHER_ARGS should be sequences of specifications for matching & completing words on the command line. +These sequences can be separated by '|' to represent alternative sequences of words. +You can use bracketing to arbitrary depth to specify alternate subsequences, but the brackets must be backslashed like this \( \) +or quoted like this '(' ')'. + +For example: +#+BEGIN_SRC sh +_regex_arguments _cmd SEQ1 '|' SEQ2 \( SEQ2a '|' SEQ2b \) +_cmd "$@" +#+END_SRC +this specifies a command line matching either SEQ1, or SEQ2 followed by SEQ2a or SEQ2b. + +Each specification in a sequence must contain a / PATTERN/ part at the start followed by an optional ':TAG:DESCRIPTION:ACTION' +part. + +Each PATTERN is a regular expression to match a word on the command line. These patterns are processed sequentially +until we reach a pattern that doesn't match at which point any corresponding ACTION is performed to obtain completions +for that word. Note that there needs to be a pattern to match the initial command itself. +See below for further explanation about PATTERNs. + +The ':TAG:DESCRIPTION:ACTION' part is interpreted in the same way as for the _alternative function specifications, +except that it has an extra : at the start, and now all of the possible ACTION formats listed previously are allowed. + +Here is an example: +#+BEGIN_SRC sh +_regex_arguments _hello /$'[^\0]##\0'/ \( /$'word1(a|b|c)\0'/ ':word:first word:(word1a word1b word1c)' '|'\ + /$'word11(a|b|c)\0'/ ':word:first word:(word11a word11b word11c)' \( /$'word2(a|b|c)\0'/ ':word:second word:(word2a word2b word2c)'\ + '|' /$'word22(a|b|c)\0'/ ':word:second word:(word22a word22b word22c)' \) \) +_cmd "$@" +#+END_SRC +in this case the first word can be word1 or word11 followed by an a, b or c, and if the first word contains 11 then a second +word is allowed which can be word2 followed by and a, b, or c, or a filename. + +If this sounds too complicated a much simpler alternative is to use the _regex_words function for creating +specifications for _regex_arguments. +*** Patterns +You may notice that the / PATTERN/ specs in the previous example don't look like normal regular expressions. +Often a string parameter in the form $'foo\0' is used. This is so that the \0 in the string is interpreted correctly +as a null char which is used to separate words in the internal representation. If you don't include the \0 at the end +of the pattern you may get problems matching the next word. If you need to use the contents of a variable in a pattern, +you can double quote it so that it gets expanded and then put a string parameter containing a null char afterwards, +like this: "$somevar"$'\0' + +The regular expression syntax for patterns seems to be a bit different from normal regular expressions, +and I can't find documentation anywhere. +However I have managed to work out what the following special chars are for: +| * | wildcard - any number of chars | +| ? | wildcard - single char | +| # | zero or more of the previous char (like * in a normal regular expression) | +| ## | one or more of the previous char (like + in a normal regular expression) | +*** _regex_words +The _regex_words function makes it much easier to create specifications for _regex_arguments. +The results of calling _regex_words can be stored in a variable which can then be used instead +of a specification for _regex_arguments. + +To create a specification using _regex_words you supply it with a tag followed by a description followed by a list +of specifications for individual words. These specifications take the form 'WORD:DESCRIPTION:SPEC' where WORD is the +word to be completed, DESCRIPTION is a description for it, and SPEC can be another variable created by _regex_words +specifying words that come after the current word or blank if there are no further words. +For example: +#+BEGIN_SRC sh +_regex_words firstword 'The first word' 'word1a:a word:' 'word1b:b word:' 'word1c:c word' +#+END_SRC +the results of this function call will be stored in the $reply array, and so we should store it in another array +before $reply gets changed again, like this: +#+BEGIN_SRC sh +local -a firstword +_regex_words word 'The first word' 'word1a:a word:' 'word1b:b word:' 'word1c:c word' +firstword="$reply[@]" +#+END_SRC +we could then use it with _regex_arguments like this: +#+BEGIN_SRC sh +_regex_arguments _cmd /$'[^\0]##\0'/ "$firstword[@]" +_cmd "$@" +#+END_SRC +Note that I have added an extra pattern for the initial command word itself. + +Here is a more complex example where we call _regex_words for different words on the command line +#+BEGIN_SRC sh +local -a firstword firstword2 secondword secondword2 +_regex_words word1 'The second word' 'woo:tang clan' 'hoo:not me' +secondword=("$reply[@]") +_regex_words word2 'Another second word' 'yee:thou' 'haa:very funny!' +secondword2=("$reply[@]") +_regex_words commands 'The first word' 'foo:do foo' 'man:yeah man' 'chu:at chu' +firstword=("$reply[@]") +_regex_words word4 'Another first word' 'boo:scare somebody:$secondword' 'ga:baby noise:$secondword'\ + 'loo:go to the toilet:$secondword2' +firstword2=("$reply[@]") + +_regex_arguments _hello /$'[^\0]##\0'/ "${firstword[@]}" "${firstword2[@]}" +_hello "$@" +#+END_SRC +In this case the first word can be one of "foo", "man", "chu", "boo", "ga" or "loo". +If the first word is "boo" or "ga" then the second word can be "woo" or "hoo", +and if the first word is "loo" then the second word can be "yee" or "haa", in the other +cases there is no second word. + +For a good example of the usage of _regex_words have a look at the _ip function. +** complex completions with _values, _sep_parts, & _multi_parts +The _values, _sep_parts & _multi_parts functions can be used either on their own, or as ACTIONs in specifications for +_alternative, _arguments or _regex_arguments. The following examples may be instructive. +See the [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][official documentation]] for more info. + +Space separated list of mp3 files: +#+BEGIN_SRC sh +_values 'mp3 files' ~/*.mp3 +#+END_SRC + +Comma separated list of session id numbers: +#+BEGIN_SRC sh +_values -s , 'session id' "${(uonzf)$(ps -A o sid=)}" +#+END_SRC + +Completes foo@news:woo, or foo@news:laa, or bar@news:woo, etc: +#+BEGIN_SRC sh +_sep_parts '(foo bar)' @ '(news ftp)' : '(woo laa)' +#+END_SRC + +Complete some MAC addresses one octet at a time: +#+BEGIN_SRC sh +_multi_parts : '(00:11:22:33:44:55 00:23:34:45:56:67 00:23:45:56:67:78)' +#+END_SRC + +** Adding completion words directly using compadd +For more fine grained control you can use the builtin compadd function to add completion words directly. +This function has many different options for controlling how completions are displayed and how text on the command line +can be altered when words are completed. Read the [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][official documentation]] for full details. +Here I just give a few simple examples. + +Add some words to the list of possible completions: +#+BEGIN_SRC sh +compadd foo bar blah +#+END_SRC + +As above but also display an explanation: +#+BEGIN_SRC sh +compadd -X 'Some completions' foo bar blah +#+END_SRC + +As above but automatically insert a prefix of "what_" before the completed word: +#+BEGIN_SRC sh +compadd -P what_ foo bar blah +#+END_SRC + +As above but automatically insert a suffix of "_todo" after the completed word: +#+BEGIN_SRC sh +compadd -S _todo foo bar blah +#+END_SRC + +As above but automatically remove the "_todo" suffix if a blank char is typed after the suffix: +#+BEGIN_SRC sh +compadd -P _todo -q foo bar blah +#+END_SRC + +Add words in array $wordsarray to the list of possible completions +#+BEGIN_SRC sh +compadd -a wordsarray +#+END_SRC + +* Testing & debugging +To reload a completion function: +#+BEGIN_SRC sh +> unfunction _func +> autoload -U _func +#+END_SRC + +The following functions can be called to obtain useful information. +If the default keybindings don't work you can try pressing Alt+x and then enter the command name. +| Function | Default keybinding | Description | +|-----------------+--------------------+--------------------------------------------------------------------------------------------------------------------------------| +| _complete_help | Ctrl+x h | displays information about context names, tags, and completion functions used when completing at the current cursor position | +| _complete_help | Alt+2 Ctrl+x h | as above but displays even more information | +| _complete_debug | Ctrl+x ? | performs ordinary completion, but captures in a temporary file a trace of the shell commands executed by the completion system | +* Gotchas (things to watch out for) +Remember to include a #compdef line at the beginning of the file containing the completion function. + +Take care to use the correct type of quoting for specifications to _arguments or _regex_arguments: +use double quotes if there is a parameter that needs to be expanded in the specification, single quotes otherwise, +and make sure to use different quotes around item descriptions. + +Check that you have the correct number of :'s in the correct places for specifications for _arguments, +_alternative, _regex_arguments, etc. + +Remember to include an initial pattern to match the command word when using _regex_arguments (it does not need a matching action). + +Remember to put a null char $'\0' at the end of any PATTERN argument for _regex_arguments +* Tips +Sometimes you have a situation where there is just one option that can come after a subcommand, and zsh will complete this +automatically when tab is pressed after the subcommand. If instead you want it listed with its description before completing +you can add another empty option (i.e. \:) to the ACTION like this ':TAG:DESCRIPTION:((opt1\:"description for opt1" \:))' +Note this only applies to utility functions that use ACTIONs in their specification arguments (_arguments, _regex_arguments, etc.) + +* Other resources +[[http://wikimatze.de/writing-zsh-completion-for-padrino.html][Here]] is a nicely formatted short tutorial showing basic usage of the _arguments function, +and [[http://www.linux-mag.com/id/1106/][here]] is a slightly more advanced tutorial using the _arguments function. +[[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][Here]] is the zshcompsys man page.