diff options
Diffstat (limited to 'Completion')
74 files changed, 1643 insertions, 0 deletions
diff --git a/Completion/Base/_command_names b/Completion/Base/_command_names new file mode 100644 index 000000000..d3b8a109a --- /dev/null +++ b/Completion/Base/_command_names @@ -0,0 +1,3 @@ +#defcomp -command- + +complist -c diff --git a/Completion/Base/_condition b/Completion/Base/_condition new file mode 100644 index 000000000..3e45e1b8f --- /dev/null +++ b/Completion/Base/_condition @@ -0,0 +1,10 @@ +#defcomp -condition- + +if [[ -current -1 -o ]]; then + complist -o -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' +elif [[ -current -1 -nt || -current -1 -ot || -current -1 -ef ]]; then + _files +else + _files + complist -v +fi diff --git a/Completion/Base/_default b/Completion/Base/_default new file mode 100644 index 000000000..8bcf14f6a --- /dev/null +++ b/Completion/Base/_default @@ -0,0 +1,13 @@ +#defcomp -default- + +# We first try the `compctl's. This is without first (-T) and default (-D) +# completion. If you want them add `-T' and/or `-D' to this command. +# If there is a `compctl' for the command we are working on, we return +# immediatly. If you want to use new style completion anyway, remove the +# `|| return'. Also, you may want to use new style completion if the +# `compctl' didn't produce any matches. In that case remove the `|| return' +# and at the line `[[ -nmatches 0 ]] || return' after `compcall'. + +compcall || return + +_files diff --git a/Completion/Base/_match_pattern b/Completion/Base/_match_pattern new file mode 100644 index 000000000..c5debc0b9 --- /dev/null +++ b/Completion/Base/_match_pattern @@ -0,0 +1,31 @@ +#autoload + +# This function is called from functions that do matching whenever they +# need to build a pattern that is used to match possible completions. +# It gets the name of the calling function and two names of parameters +# as arguments. The first one is used in the calling function to build +# the pattern used for matching possible completions. The content of this +# parameter on entry to this function is the string taken from the line. +# Here it parameter should be changed to a pattern that matches words as +# the match specs currently in use do. +# In the calling function this pattern may be changed again or used only +# in parts. The second parameter whose name is given as the third argument +# allows to give pattern flags liek `(#l)' that are to be used whenever +# matching is done. +# +# As an example, if you have global match specifications like: +# +# compctl -M 'm:{a-z}={A-Z}' 'm:{a-z}={A-Z} r:|[.-]=* r:|=*' +# +# This function would look like: +# +# eval "${3}='(#l)'" +# [[ MATCHER -eq 2 ]] && eval "$1='${(P)2:gs/./*./:gs/-/*-/}'" +# +# The first line makes sure that matching is done case-insensitive as +# specified by `m:{a-z}={A-Z}'. The second line replaces dots and hyphens +# in the given string by patterns matching any characters before them, +# like the `r:|[.-]=* r:|=*'. To make this work, the function `_match_test' +# would have to be changed to `(( MATCHERS <= 2 ))' +# +# The default implementation of this function is empty. diff --git a/Completion/Base/_match_test b/Completion/Base/_match_test new file mode 100644 index 000000000..e8b6e6424 --- /dev/null +++ b/Completion/Base/_match_test @@ -0,0 +1,15 @@ +#autoload + +# This function is called at the beginning of functions that do matching in +# shell code. It should test the value of the `MATCHER' special parameter +# and return non-zero if the calling function should try to generate matches +# for the global match specification in use. +# +# This function gets one argument, the name of the function calling it. +# +# If you have a global match specification with more than one set of patterns +# you may want to modify this function to return non-zero for all of your +# match specifications and modify the function `_match_pattern' to build the +# pattern to use in the calling function. + +(( MATCHER == 1 )) diff --git a/Completion/Base/_precommand b/Completion/Base/_precommand new file mode 100644 index 000000000..2cf661147 --- /dev/null +++ b/Completion/Base/_precommand @@ -0,0 +1,5 @@ +#defcomp - nohup nice eval time rusage noglob nocorrect exec + +[[ -position 1 -1 ]] + +_normal "$@" diff --git a/Completion/Base/_redirect b/Completion/Base/_redirect new file mode 100644 index 000000000..32113ad7c --- /dev/null +++ b/Completion/Base/_redirect @@ -0,0 +1,3 @@ +#defcomp -redirect- + +_files diff --git a/Completion/Base/_subscript b/Completion/Base/_subscript new file mode 100644 index 000000000..2b827a117 --- /dev/null +++ b/Completion/Base/_subscript @@ -0,0 +1,4 @@ +#defcomp -subscript- + +_compalso -math- "$@" +[[ ${(Pt)${COMMAND}} = assoc* ]] && complist -k "( ${(kP)${COMMAND}} )" diff --git a/Completion/Base/_vars b/Completion/Base/_vars new file mode 100644 index 000000000..7153b6f38 --- /dev/null +++ b/Completion/Base/_vars @@ -0,0 +1,3 @@ +#defcomp -math- getopts read unset vared + +complist -v diff --git a/Completion/Builtins/_aliases b/Completion/Builtins/_aliases new file mode 100644 index 000000000..1038a726e --- /dev/null +++ b/Completion/Builtins/_aliases @@ -0,0 +1,3 @@ +#defcomp unalias + +complist -a diff --git a/Completion/Builtins/_arrays b/Completion/Builtins/_arrays new file mode 100644 index 000000000..cbeac7118 --- /dev/null +++ b/Completion/Builtins/_arrays @@ -0,0 +1,3 @@ +#defcomp shift + +complist -A diff --git a/Completion/Builtins/_autoload b/Completion/Builtins/_autoload new file mode 100644 index 000000000..4f506baeb --- /dev/null +++ b/Completion/Builtins/_autoload @@ -0,0 +1,3 @@ +#defcomp autoload + +complist -s '${^fpath}/*(N:t)' diff --git a/Completion/Builtins/_bg_jobs b/Completion/Builtins/_bg_jobs new file mode 100644 index 000000000..511bb8308 --- /dev/null +++ b/Completion/Builtins/_bg_jobs @@ -0,0 +1,3 @@ +#defcomp bg + +complist -z -P '%' diff --git a/Completion/Builtins/_bindkey b/Completion/Builtins/_bindkey new file mode 100644 index 000000000..8eddeb2a8 --- /dev/null +++ b/Completion/Builtins/_bindkey @@ -0,0 +1,7 @@ +#defcomp bindkey + +if [[ -mword 1 -*[DAN]* || -mcurrent -1 -*M ]]; then + complist -s '$(bindkey -l)' +else + complist -b +fi diff --git a/Completion/Builtins/_builtin b/Completion/Builtins/_builtin new file mode 100644 index 000000000..a967932ee --- /dev/null +++ b/Completion/Builtins/_builtin @@ -0,0 +1,7 @@ +#defcomp builtin + +if [[ -position 2 -1 ]]; then + _normal "$@" +else + complist -eB +fi diff --git a/Completion/Builtins/_cd b/Completion/Builtins/_cd new file mode 100644 index 000000000..f3ce67ec7 --- /dev/null +++ b/Completion/Builtins/_cd @@ -0,0 +1,3 @@ +#defcomp cd + +_files -W cdpath -g '*(-/)' diff --git a/Completion/Builtins/_command b/Completion/Builtins/_command new file mode 100644 index 000000000..b2812de25 --- /dev/null +++ b/Completion/Builtins/_command @@ -0,0 +1,7 @@ +#defcomp command + +if [[ -position 2 -1 ]]; then + _normal "$@" +else + complist -em +fi diff --git a/Completion/Builtins/_dirs b/Completion/Builtins/_dirs new file mode 100644 index 000000000..bc426e322 --- /dev/null +++ b/Completion/Builtins/_dirs @@ -0,0 +1,3 @@ +#defcomp rmdir df du dircmp + +_files -/ diff --git a/Completion/Builtins/_disable b/Completion/Builtins/_disable new file mode 100644 index 000000000..063b65a7d --- /dev/null +++ b/Completion/Builtins/_disable @@ -0,0 +1,6 @@ +#defcomp disable + +[[ -mcurrent -1 -*a* ]] && complist -ea +[[ -mcurrent -1 -*f* ]] && complist -eF +[[ -mcurrent -1 -*r* ]] && complist -ew +[[ ! -mcurrent -1 -* ]] && complist -eB diff --git a/Completion/Builtins/_echotc b/Completion/Builtins/_echotc new file mode 100644 index 000000000..85ebb97ce --- /dev/null +++ b/Completion/Builtins/_echotc @@ -0,0 +1,3 @@ +#defcomp echotc + +complist -k '(al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up)' diff --git a/Completion/Builtins/_enable b/Completion/Builtins/_enable new file mode 100644 index 000000000..22ff53ee7 --- /dev/null +++ b/Completion/Builtins/_enable @@ -0,0 +1,6 @@ +#defcomp enable + +[[ -mcurrent -1 -*a* ]] && complist -da +[[ -mcurrent -1 -*f* ]] && complist -dF +[[ -mcurrent -1 -*r* ]] && complist -dw +[[ ! -mcurrent -1 -* ]] && complist -dB diff --git a/Completion/Builtins/_fc b/Completion/Builtins/_fc new file mode 100644 index 000000000..f0d2c03fd --- /dev/null +++ b/Completion/Builtins/_fc @@ -0,0 +1,7 @@ +#defcomp fc + +if [[ -mcurrent -1 -*e ]]; then + complist -c +elif [[ -mcurrent -1 -[ARWI]## ]]; then + _files +fi diff --git a/Completion/Builtins/_functions b/Completion/Builtins/_functions new file mode 100644 index 000000000..8a352ea08 --- /dev/null +++ b/Completion/Builtins/_functions @@ -0,0 +1,3 @@ +#defcomp unfunction + +complist -F diff --git a/Completion/Builtins/_hash b/Completion/Builtins/_hash new file mode 100644 index 000000000..171c5e2e8 --- /dev/null +++ b/Completion/Builtins/_hash @@ -0,0 +1,13 @@ +#defcomp hash + +if [[ -mword 1 -*d* ]]; then + if [[ -string 1 '=' ]]; then + _path_files -g '*(-/)' + else + complist -n -q -S '=' + fi +elif [[ -string 1 '=' ]]; then + _files -/g '*(*)' +else + complist -m -q -S '=' +fi diff --git a/Completion/Builtins/_jobs b/Completion/Builtins/_jobs new file mode 100644 index 000000000..018883c61 --- /dev/null +++ b/Completion/Builtins/_jobs @@ -0,0 +1,3 @@ +#defcomp fg jobs + +complist -j -P '%' diff --git a/Completion/Builtins/_kill b/Completion/Builtins/_kill new file mode 100644 index 000000000..50796d36f --- /dev/null +++ b/Completion/Builtins/_kill @@ -0,0 +1,11 @@ +#defcomp kill + +local list + +if [[ -iprefix '-' ]]; then + complist -k "($signals[1,-3])" +else + complist -P '%' -j + list=("$(ps 2>/dev/null)") + complist -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' +fi diff --git a/Completion/Builtins/_limits b/Completion/Builtins/_limits new file mode 100644 index 000000000..35ccbe07e --- /dev/null +++ b/Completion/Builtins/_limits @@ -0,0 +1,3 @@ +#defcomp limit unlimit + +complist -k "(${(j: :)${(f)$(limit)}%% *})" diff --git a/Completion/Builtins/_sched b/Completion/Builtins/_sched new file mode 100644 index 000000000..1e8ae3445 --- /dev/null +++ b/Completion/Builtins/_sched @@ -0,0 +1,3 @@ +#defcomp sched + +[[ -position 2 -1 ]] && _normal "$@" diff --git a/Completion/Builtins/_set b/Completion/Builtins/_set new file mode 100644 index 000000000..5597025bc --- /dev/null +++ b/Completion/Builtins/_set @@ -0,0 +1,7 @@ +#defcomp set + +if [[ -mcurrent -1 [-+]o ]]; then + complist -o +elif [[ -current -1 -A ]]; then + complist -A +fi diff --git a/Completion/Builtins/_setopt b/Completion/Builtins/_setopt new file mode 100644 index 000000000..4abb3ccee --- /dev/null +++ b/Completion/Builtins/_setopt @@ -0,0 +1,7 @@ +#defcomp setopt + +local nm=$NMATCHES + +complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \ + -s '$({ unsetopt kshoptionprint; unsetopt } 2>/dev/null)' +[[ -nmatches nm ]] && complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o diff --git a/Completion/Builtins/_source b/Completion/Builtins/_source new file mode 100644 index 000000000..aae2c7320 --- /dev/null +++ b/Completion/Builtins/_source @@ -0,0 +1,7 @@ +#defcomp source + +if [[ -position 2 -1 ]]; then + _normal "$@" +else + _files +fi diff --git a/Completion/Builtins/_trap b/Completion/Builtins/_trap new file mode 100644 index 000000000..59e81c589 --- /dev/null +++ b/Completion/Builtins/_trap @@ -0,0 +1,7 @@ +#defcomp trap + +if [[ -position 1 ]]; then + complist -c +else + complist -k signals +fi diff --git a/Completion/Builtins/_unhash b/Completion/Builtins/_unhash new file mode 100644 index 000000000..fe40c25a2 --- /dev/null +++ b/Completion/Builtins/_unhash @@ -0,0 +1,6 @@ +#defcomp unhash + +[[ -mword 1 -*d* ]] && complist -n +[[ -mword 1 -*a* ]] && complist -a +[[ -mword 1 -*f* ]] && complist -F +[[ ! -mword 1 -* ]] && complist -m diff --git a/Completion/Builtins/_unsetopt b/Completion/Builtins/_unsetopt new file mode 100644 index 000000000..90d642b51 --- /dev/null +++ b/Completion/Builtins/_unsetopt @@ -0,0 +1,7 @@ +#defcomp unsetopt + +local nm=$NMATCHES + +complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \ + -s '$({ unsetopt kshoptionprint; setopt } 2>/dev/null)' +[[ -nmatches nm ]] && complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o diff --git a/Completion/Builtins/_vars_eq b/Completion/Builtins/_vars_eq new file mode 100644 index 000000000..fcbb0148c --- /dev/null +++ b/Completion/Builtins/_vars_eq @@ -0,0 +1,3 @@ +#defcomp declare export integer local readonly typeset + +complist -v -q -S '=' diff --git a/Completion/Builtins/_wait b/Completion/Builtins/_wait new file mode 100644 index 000000000..29a7f6002 --- /dev/null +++ b/Completion/Builtins/_wait @@ -0,0 +1,7 @@ +#defcomp wait + +local list + +complist -P '%' -j +list=("$(ps 2>/dev/null)") +complist -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' diff --git a/Completion/Builtins/_which b/Completion/Builtins/_which new file mode 100644 index 000000000..324256e3d --- /dev/null +++ b/Completion/Builtins/_which @@ -0,0 +1,3 @@ +#defcomp which whence where type + +complist -caF diff --git a/Completion/Builtins/_zftp b/Completion/Builtins/_zftp new file mode 100644 index 000000000..9be9c94db --- /dev/null +++ b/Completion/Builtins/_zftp @@ -0,0 +1,50 @@ +#defpatcomp zf* + +# Don't try any more completion after this. +_compskip=1 + +# Completion for zftp builtin and zf* functions. The functions +# zfcd_match and zfget_match (used for old-style completion) +# need to be installed for remote file and directory completion to work. + +local subcom + +if [[ $COMMAND = zftp ]]; then + if [[ $CURRENT -eq 1 ]]; then + compadd -m open params user login type ascii binary mode put \ + putat get getat append appendat ls dir local remote mkdir rmdir + return + fi + subcom=$1 +else + subcom=$COMMAND +fi + +case $subcom in + *(cd|ls|dir)) + # complete remote directories; we could be smarter about hiding prefixes + zfcd_match $PREFIX $SUFFIX + (( $#reply )) && compadd -m -S/ -q $reply + ;; + + *(get(|at)|gcp|delete|remote)) + # complete remote files + zfget_match $PREFIX $SUFFIX + (( $#reply )) && compadd -F fignore -m $reply + ;; + + *(put(|at)|pcp)) + # complete local files + _files + ;; + + *(open|anon|params)) + # complete hosts: should do cleverer stuff with user names + complist -k hosts + ;; + + *) + # dunno... try ordinary completion after all. + unset _compskip + ;; +esac diff --git a/Completion/Builtins/_zle b/Completion/Builtins/_zle new file mode 100644 index 000000000..bb1102e74 --- /dev/null +++ b/Completion/Builtins/_zle @@ -0,0 +1,7 @@ +#defcomp zle + +if [[ -word 1 -N && -position 3 ]]; then + complist -F +else + complist -b +fi diff --git a/Completion/Builtins/_zmodload b/Completion/Builtins/_zmodload new file mode 100644 index 000000000..112acb57c --- /dev/null +++ b/Completion/Builtins/_zmodload @@ -0,0 +1,9 @@ +#defcomp zmodload + +if [[ -mword 1 -*(a*u|u*a)* || -mword 1 -*a* && -position 3 -1 ]]; then + complist -B +elif [[ -mword 1 -*u* ]]; then + complist -s '$(zmodload)' +else + complist -s '${^module_path}/*(N:t:r)' +fi diff --git a/Completion/Commands/_correct_filename b/Completion/Commands/_correct_filename new file mode 100644 index 000000000..edf1c65c2 --- /dev/null +++ b/Completion/Commands/_correct_filename @@ -0,0 +1,37 @@ +#defkeycomp complete-word \C-xc + +# Function to correct a filename. Can be used as a completion widget, +# or as a function in its own right, in which case it will print the +# corrected filename to standard output. +# +# You can adapt max_approx to the maximum number of mistakes +# which are allowed in total. + +emulate -LR zsh +setopt extendedglob + +local file="$PREFIX$SUFFIX" trylist +integer approx max_approx=6 + +[[ -z $WIDGET ]] && file=$1 + +if [[ -e "$file" ]]; then + if [[ -n $WIDGET ]]; then + compadd "$file" + else + print "$file" + fi + return +fi + +for (( approx = 1; approx <= max_approx; approx++ )); do + trylist=( (#a$approx)"$file"(N) ) + (( $#trylist )) && break +done +(( $#trylist )) || return 1 + +if [[ -n $WIDGET ]]; then + compadd -U "${trylist[@]}" +else + print "${trylist[@]}" +fi diff --git a/Completion/Commands/_most_recent_file b/Completion/Commands/_most_recent_file new file mode 100644 index 000000000..ff5645de5 --- /dev/null +++ b/Completion/Commands/_most_recent_file @@ -0,0 +1,4 @@ +#defkeycomp complete-word \C-xm +local file +file=($~PREFIX*$~SUFFIX(om[1]N)) +(( $#file )) && compadd -f $file diff --git a/Completion/Core/_comp_parts b/Completion/Core/_comp_parts new file mode 100644 index 000000000..7c24fd19d --- /dev/null +++ b/Completion/Core/_comp_parts @@ -0,0 +1,147 @@ +#autoload + +# This function can be used to separately complete parts of strings +# where each part may be one of a set of matches and different parts +# have different sets. +# Arguments are alternatingly arrays and separator strings. Arrays may +# be given by name or literally as words separated by white space in +# parentheses, e.g.: +# +# _comp_parts '(foo bar)' @ hosts +# +# This will make this function complete the strings in the array +# `friends'. If the string on the line contains a `@', the substring +# after it will be completed from the array `hosts'. Of course more +# arrays may be given, each preceded by another separator string. +# +# This function understands the `-J group', `-V group', and +# `-X explanation' options. +# +# This function does part of the matching itself and calls the functions +# `_match_test' and `_match_pattern' for this. + +local str arr sep test testarr tmparr prefix suffixes matchers autosuffix +local matchflags opt group expl + +# Test if we should use this function for the global matcher in use. + +_match_test _comp_parts || return + +# Get the options. + +group=() +expl=() +while getopts "J:V:X:" opt; do + case "$opt" in + [JV]) group=("-$opt" "$OPTARG");; + X) expl=(-X "$OPTARG");; + esac +done +shift OPTIND-1 + +# Get the string from the line. + +str="$PREFIX$SUFFIX" +prefix="" + +# Walk through the arguments to find the longest unambiguous prefix. + +while [[ $# -gt 1 ]]; do + # Get the next array and separator. + arr="$1" + sep="$2" + + if [[ "$arr[1]" == '(' ]]; then + tmparr=( ${=arr[2,-2]} ) + arr=tmparr + fi + # Is the separator on the line? + [[ "$str" != *${sep}* ]] && break + + # Build a pattern matching the possible matches and get all these + # matches in an array. + test="${str%%${sep}*}" + matchflags="" + _match_pattern _comp_parts test matchflags + test="${matchflags}${test}" + testarr=( "${(@M)${(@P)arr}:#${~test}*}" ) + + # If there are no matches we give up. If there is more than one + # match, this is the part we will complete. + (( $#testarr )) || return + [[ $#testarr -gt 1 ]] && break + + # Only one match, add it to the prefix and skip over it in `str', + # continuing with the next array and separator. + prefix="${prefix}${testarr[1]}${sep}" + str="${str#*${sep}}" + shift 2 +done + +# Get the array to work upon. +arr="$1" +if [[ "$arr[1]" == '(' ]]; then + tmparr=( ${=arr[2,-2]} ) + arr=tmparr +fi +if [[ $# -le 1 || "$str" != *${2}* ]]; then + # No more separators, build the matches. + matchflags="" + test="$str" + _match_pattern _comp_parts test matchflags + test="${matchflags}${test}" + testarr=( "${(@M)${(@P)arr}:#${~test}*}" ) +fi + +[[ $#testarr -eq 0 || ${#testarr[1]} -eq 0 ]] && return + +# Now we build the suffixes to give to the completion code. +shift +matchers=() +suffixes=("") +autosuffix=() + +while [[ $# -gt 0 && "$str" == *${1}* ]]; do + # Remove anything up to the the suffix. + str="${str#*${1}}" + + # Again, we get the string from the line up to the next separator + # and build a pattern from it. + if [[ $# -gt 2 ]]; then + test="${str%%${3}*}" + else + test="$str" + fi + matchflags="" + _match_pattern _comp_parts test matchflags + test="${matchflags}${test}" + + # We incrementally add suffixes by appending to them the seperators + # and the strings from the next array that match the pattern we built. + + arr="$2" + if [[ "$arr[1]" == '(' ]]; then + tmparr=( ${=arr[2,-2]} ) + arr=tmparr + fi + suffixes=("${^suffixes[@]}${1}${(@M)^${(@P)arr}:#${~test}*}") + + # We want the completion code to generate the most specific suffix + # for us, so we collect matching specifications that allow partial + # word matching before the separators on the fly. + matchers=("$matchers[@]" "r:|${1}=*") + shift 2 +done + +# If we were given at least one more separator we make the completion +# code offer it by appending it as a autoremovable suffix. +(( $# )) && autosuffix=(-qS "$1") + +# If we have collected matching specifications, we build an array +# from it that can be used as arguments to `compadd'. +[[ $#matchers -gt 0 ]] && matchers=(-M "$matchers") + +# Add the matches for each of the suffixes. +for i in "$suffixes[@]"; do + compadd "$group[@]" "$expl[@]" "$matchers[@]" "$autosuffix[@]" -p "$prefix" -s "$i" - "$testarr[@]" +done diff --git a/Completion/Core/_compalso b/Completion/Core/_compalso new file mode 100644 index 000000000..23a40e2d0 --- /dev/null +++ b/Completion/Core/_compalso @@ -0,0 +1,13 @@ +#autoload + +# This searches $1 in the array for normal completions and calls the result. +# It is used to include completions for another command or special context +# into the list generated by the calling function. +# For example the function for `-subscript-' could call this as in +# `_compalso -math- "$@"' to get the completions that would be generated +# for a mathematical context. + +local tmp + +tmp="$_comps[$1]" +[[ -z "$tmp" ]] || "$tmp" "$@" diff --git a/Completion/Core/_files b/Completion/Core/_files new file mode 100644 index 000000000..d2cce35e7 --- /dev/null +++ b/Completion/Core/_files @@ -0,0 +1,26 @@ +#autoload + +# Utility function for completing files of a given type or any file. +# In many cases you will want to call this one instead of _path_files(). + +local nm=$NMATCHES + +_path_files "$@" + +if [[ $# -ne 0 && -nmatches nm ]]; then + local opt opts + + # We didn't get any matches for those types of files described by + # the `-g' or `-/' option. Now we try it again accepting all files. + # First we get those options that we have to use even if then. If + # we find out that the `-f' option was given, we already accepted + # all files and give up immediatly. + + opts=() + while getopts "P:S:W:F:J:V:X:f/g:" opt; do + [[ "$opt" = f ]] && return + [[ "$opt" = [PSWFJVX] ]] && opts=("$opts[@]" "-$opt" "$OPTARG") + done + + _path_files "$opts[@]" +fi diff --git a/Completion/Core/_main_complete b/Completion/Core/_main_complete new file mode 100644 index 000000000..c7f5a5a96 --- /dev/null +++ b/Completion/Core/_main_complete @@ -0,0 +1,48 @@ +#autoload + +# The main loop of the completion code. This is what is called when +# completion is attempted from the command line. +# The completion code gives us the special variables and the arguments +# from the command line are given as positional parameters. + +local comp name + +setopt localoptions nullglob rcexpandparam globdots +unsetopt markdirs globsubst shwordsplit nounset + +# An entry for `-first-' is the replacement for `compctl -T' +# Completion functions may set `_compskip' to any value to make the +# main loops stop calling other completion functions. + +comp="$_comps[-first-]" +if [[ ! -z "$comp" ]]; then + "$comp" "$@" + if (( $+_compskip )); then + unset _compskip + return + fi +fi + +# For arguments we use the `_normal function. + +if [[ $CONTEXT == argument || $CONTEXT == command ]]; then + _normal "$@" +else + # Let's see if we have a special completion definition for the other + # possible contexts. + + comp='' + + case $CONTEXT in + redirect) comp="$_comps[-redirect-]";; + math) comp="$_comps[-math-]";; + subscript) comp="$_comps[-subscript-]";; + value) comp="$_comps[-value-]";; + condition) comp="$_comps[-condition-]";; + esac + + # If not, we use default completion, if any. + + [[ -z "$comp" ]] && comp="$_comps[-default-]" + [[ -z "$comp" ]] || "$comp" "$@" +fi diff --git a/Completion/Core/_normal b/Completion/Core/_normal new file mode 100644 index 000000000..19da6d79b --- /dev/null +++ b/Completion/Core/_normal @@ -0,0 +1,54 @@ +#autoload + +local comp cmd1 cmd2 pat val name + +# Completing in command position? If not we set up `cmd1' and `cmd2' as +# two strings we have search in the completion definition arrays (e.g. +# a path and the last path name component). + +if [[ $CONTEXT == command ]]; then + comp="$_comps[-command-]" + [[ -z "$comp" ]] || "$comp" "$@" + return +elif [[ "$COMMAND[1]" == '=' ]]; then + eval cmd1\=$COMMAND + cmd2="$COMMAND[2,-1]" +elif [[ "$COMMAND" == */* ]]; then + cmd1="$COMMAND" + cmd2="${COMMAND:t}" +else + cmd1="$COMMAND" + eval cmd2=$(whence -p $COMMAND) +fi + +# See if there are any matching pattern completions. + +for i in "$_patcomps[@]"; do + pat="${i% *}" + val="${i#* }" + if [[ "$cmd1" == $~pat || "$cmd2" == $~pat ]]; then + "$val" "$@" + if (( $+_compskip )); then + unset _compskip + return + fi + fi +done + +# Now look up the two names in the normal completion array. + +name="$cmd1" +comp="$_comps[$cmd1]" + +if [[ -z "$comp" ]]; then + name="$cmd2" + comp="$_comps[$cmd2]" +fi + +# And generate the matches, probably using default completion. + +if [[ -z "$comp" ]]; then + name=-default- + comp="$_comps[-default-]" +fi +[[ -z "$comp" ]] || "$comp" "$@" diff --git a/Completion/Core/_path_files b/Completion/Core/_path_files new file mode 100644 index 000000000..83b6e8a09 --- /dev/null +++ b/Completion/Core/_path_files @@ -0,0 +1,311 @@ +#autoload + +# Utility function for in-path completion. +# Supported arguments are: `-f', `-/', `-g <patterns>', `-J <group>', +# `-V <group>', `-W paths', `-X explanation', and `-F <ignore>'. All but +# the last have the same syntax and meaning as for `complist'. The +# `-F <ignore>' option may be used to give a list of suffixes either by +# giving the name of an array or literally by giving them in a string +# surrounded by parentheses. Files with one of the suffixes thus given +# are treated like files with one of the suffixes in the `fignore' array +# in normal completion. +# +# This function uses the helper functions `_match_test' and `_match_pattern'. + +# First see if we should generate matches for the global matcher in use. + +_match_test _path_files || return + +# Yes, so... + +local nm prepaths str linepath realpath donepath patstr prepath testpath rest +local tmp1 collect tmp2 suffixes i ignore matchflags opt group sopt pats gopt +local addpfx addsfx expl + +setopt localoptions nullglob rcexpandparam globdots extendedglob +unsetopt markdirs globsubst shwordsplit nounset + +prepaths=('') +ignore=() +group=() +sopt='-' +gopt='' +pats=() +addpfx=() +addsfx=() +expl=() + +# Get the options. + +while getopts "P:S:W:F:J:V:X:f/g:" opt; do + case "$opt" in + P) addpfx=(-P "$OPTARG") + ;; + S) addsfx=(-S "$OPTARG") + ;; + W) tmp1="$OPTARG" + if [[ "$tmp1[1]" = '(' ]]; then + prepaths=( ${^=tmp1[2,-2]}/ ) + else + prepaths=( ${(P)=${tmp1}} ) + (( ! $#prepaths )) && prepaths=( ${tmp1}/ ) + fi + (( ! $#prepaths )) && prepaths=( '' ) + ;; + F) tmp1="$OPTARG" + if [[ "$tmp1[1]" = '(' ]]; then + ignore=( ${^=tmp1[2,-2]}/ ) + else + ignore=( ${(P)${tmp1}} ) + fi + (( $#ignore )) && ignore=(-F "( $ignore )") + ;; + [JV]) group=("-$opt" "$OPTARG") + ;; + X) expl=(-X "$OPTARG") + ;; + f) sopt="${sopt}f" + pats=("$pats[@]" '*') + ;; + /) sopt="${sopt}/" + pats=("$pats[@]" '*(-/)') + ;; + g) gopt='-g' + pats=("$pats[@]" ${=OPTARG}) + ;; + esac +done + +# If we were given no file selection option, we behave as if we were given +# a `-f'. + +if [[ "$sopt" = - ]]; then + if [[ -z "$gopt" ]]; then + sopt='-f' + pats=('*') + else + unset sopt + fi +fi + +# str holds the whole string from the command line with a `*' between +# the prefix and the suffix. + +str="${PREFIX:q}*${SUFFIX:q}" + +# If the string began with a `~', the quoting turned this into `\~', +# remove the slash. + +[[ "$str" = \\\~* ]] && str="$str[2,-1]" + +# We will first try normal completion called with `complist', but only if we +# weren't given a `-F' option. + +if (( ! $#ignore )); then + # First build an array containing the `-W' option, if there is any and we + # want to use it. We don't want to use it if the string from the command line + # is a absolute path or relative to the current directory. + + if [[ -z "$tmp1[1]" || "$str[1]" = [~/] || "$str" = (.|..)/* ]]; then + tmp1=() + else + tmp1=(-W "( $prepaths )") + fi + + # Now call complist. + + nm=$NMATCHES + if [[ -z "$gopt" ]]; then + complist "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" "$tmp1[@]" $sopt + else + complist "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" "$tmp1[@]" $sopt -g "$pats" + fi + + # If this generated any matches, we don't want to do in-path completion. + + [[ -nmatches nm ]] || return + + # No `-F' option, so we want to use `fignore'. + + ignore=(-F fignore) +fi + +# Now let's have a closer look at the string to complete. + +if [[ "$str[1]" = \~ ]]; then + # It begins with `~', so remember anything before the first slash to be able + # to report it to the completion code. Also get an expanded version of it + # (in `realpath'), so that we can generate the matches. Then remove that + # prefix from the string to complete, set `donepath' to build the correct + # paths and make sure that the loop below is run only once with an empty + # prefix path by setting `prepaths'. + + linepath="${str%%/*}/" + eval realpath\=$linepath + str="${str#*/}" + donepath='' + prepaths=( '' ) +else + # If the string does not start with a `~' we don't remove a prefix from the + # string. + + liniepath='' + realpath='' + + if [[ "$str[1]" = / ]]; then + # If it is a absolut path name, we remove the first slash and put it in + # `donepath' meaning that we treat it as the path that was already handled. + # Also, we don't use the paths from `-W'. + + str="$str[2,-1]" + donepath='/' + prepaths=( '' ) + else + # The common case, we just use the string as it is, unless it begins with + # `./' or `../' in which case we don't use the paths from `-W'. + + [[ "$str" = (.|..)/* ]] && prepaths=( '' ) + donepath='' + fi +fi + +# First we skip over all pathname components in `str' which really exist in +# the file-system, so that `/usr/lib/l<TAB>' doesn't offer you `lib' and +# `lib5'. Pathname components skipped this way are taken from `str' and added +# to `donepath'. + +while [[ "$str" = */* ]] do + [[ -e "$realpath$donepath${str%%/*}" ]] || break + donepath="$donepath${str%%/*}/" + str="${str#*/}" +done + +# Now build the glob pattern by calling `_match_pattern'. +patstr="$str" +matchflags="" +_match_pattern _path_files patstr matchflags + +# We almost expect the pattern to have changed `..' into `*.*.', `/.' into +# `/*.', and probably to contain two or more consecutive `*'s. Since these +# have special meaning for globbing, we remove them. But before that, we +# add the pattern for matching any characters before a slash. + +patstr="$patstr:gs-/-*/-:gs/*.*.//:gs-/*.-/.-:gs/**/*/" + +# Finally, generate the matches. First we loop over all the paths from `-W'. +# Note that in this loop `str' is used as a modifyable version of `patstr' +# and `testpath' is a modifyable version of `donepath'. + +for prepath in "$prepaths[@]"; do + str="$patstr" + testpath="$donepath" + + # The second loop tests the components of the path in `str' to get the + # possible matches. + + while [[ "$str" = */* ]] do + # `rest' is the pathname after the first slash that is left. In `tmp1' + # we get the globbing matches for the pathname component currently + # handled. + + rest="${str#*/}" + tmp1="${prepath}${realpath}${testpath}${~matchflags}${str%%/*}(-/)" + tmp1=( $~tmp1 ) + + if [[ $#tmp1 -eq 0 ]]; then + # If this didn't produce any matches, we don't need to test this path + # any further, so continue with the next `-W' path, if any. + + continue 2 + elif [[ $#tmp1 -gt 1 ]]; then + # If it produced more than one match, we want to remove those which + # don't have possible following pathname components matching the + # rest of the string we are completing. (The case with only one + # match is handled below.) + # In `collect' we will collect those of the produced pathnames that + # have a matching possible path-suffix. In `suffixes' we build an + # array containing strings build from the rest of the string to + # complete and the glob patterns we were given as arguments. + + collect=() + suffixes=( $rest$^pats ) + suffixes=( "${(@)suffixes:gs.**.*.}" ) + + # In the loop the prefixes from the `tmp1' array produced above and + # the suffixes we just built are used to produce possible matches + # via globbing. + + for i in $tmp1; do + tmp2=( ${~i}/${~matchflags}${~suffixes} ) + [[ $#tmp2 -ne 0 ]] && collect=( $collect $i ) + done + + # If this test showed that none of the matches from the glob in `tmp1' + # has a possible sub-path matching what's on the line, we give up and + # continue with the next `-W' path. + + if [[ $#collect -eq 0 ]]; then + continue 2 + elif [[ $#collect -ne 1 ]]; then + # If we have more than one possible match, this means that the + # pathname component currently handled is ambiguous, so we give + # it to the completion code. + # First we build the full path prefix in `tmp1'. + + tmp1="$prepath$realpath$testpath" + + # Now produce all matching pathnames in `collect'. + + collect=( ${~collect}/${~matchflags}${~suffixes} ) + + # And then remove the common path prefix from all these matches. + + collect=( ${collect#$tmp1} ) + + # Finally, we add all these matches with the common (unexpanded) + # pathprefix (the `-p' option), the path-prefix (the `-W' option) + # to allow the completion code to test file type, and the path- + # suffix (the `-s' option). We also tell the completion code that + # these are file names and that `fignore' should be used as usual + # (the `-f' and `-F' options). + + for i in $collect; do + compadd "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" -p "$linepath$testpath" -W "$tmp1" -s "/${i#*/}" -f "$ignore[@]" - "${i%%/*}" + done + + # We have just finished handling all the matches from above, so we + # can continue with the next `-W' path. + + continue 2 + fi + # We reach this point if only one of the path prefixes in `tmp1' + # has a existing path-suffix matching the string from the line. + # In this case we accept this match and continue with the next + # path-name component. + + tmp1=( "$collect[1]" ) + fi + # This is also reached if the first globbing produced only one match + # in this case we just continue with the next pathname component, too. + + tmp1="$tmp1[1]" + testpath="$testpath${tmp1##*/}/" + str="$rest" + done + + # We are here if all pathname components except the last one (which is still + # not tested) are unambiguous. So we add matches with the full path prefix, + # no path suffix, the `-W' we are currently handling, all the matches we + # can produce in this directory, if any. + + tmp1="$prepath$realpath$testpath" + suffixes=( $str$^pats ) + suffixes=( "${(@)suffixes:gs.**.*.}" ) + tmp2=( ${~tmp1}${~matchflags}${~suffixes} ) + if [[ $#tmp2 -eq 0 && "$sopt" = */* ]]; then + [[ "$testpath[-1]" = / ]] && testpath="$testpath[1,-2]" + compadd "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" -f - "$linepath$testpath" + else + compadd "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" -p "$linepath$testpath" -W "$prepath$realpath$testpath" -f "$ignore[@]" - ${(@)tmp2#$tmp1} + fi +done diff --git a/Completion/Core/compdump b/Completion/Core/compdump new file mode 100644 index 000000000..8be096f50 --- /dev/null +++ b/Completion/Core/compdump @@ -0,0 +1,89 @@ +# This is a file to be sourced to dump the definitions for new-style +# completion defined by 'compinit' in the same directory. The output +# should be directed into the "compinit.dump" in the same directory as +# compinit. If you rename init, just stick .dump onto the end of whatever +# you have called it and put it in the same directory. This is handled +# automatically if you invoke compinit with the option -d. +# +# You will need to update the dump every time you add a new completion. +# To do this, simply remove the .dump file, start a new shell, and +# create the .dump file as before. Again, compinit -d handles this +# automatically. +# +# It relies on KSH_ARRAYS not being set. + +# Print the number of files used for completion. This is used in compinit +# to see if auto-dump should re-dump the dump-file. + +_d_file=${COMPDUMP-${0:h}/compinit.dump} + +typeset -U _d_files +_d_files=( ${^~fpath}/_*~*~(N:t) ) + +print "#files: $#_d_files" > $_d_file + +unset _d_files + +# First dump the arrays _comps and _patcomps. The quoting hieroglyphyics +# ensure that a single quote inside a variable is itself correctly quoted. + +print "_comps=(" >> $_d_file +for _d_f in ${(ok)_comps}; do + print -r - "'${_d_f//\'/'\\''}'" "'${_comps[$_d_f]//\'/'\\''}'" +done >> $_d_file +print ")" >> $_d_file + +print "\n_patcomps=(" >> $_d_file +for _d_f in "$_patcomps[@]"; do + print -r - "'${_d_f//\'/'\\''}'" +done >> $_d_file +print ")" >> $_d_file + +print >> $_d_file + +# Now dump the key bindings. We dump all bindings for zle widgets +# whose names start with a underscore. +# We need both the zle -C's and the bindkey's to recreate. + +_d_bks=() +zle -lL | + while read -rA _d_line; do + if [[ ${_d_line[5]} = _* ]]; then + print -r - ${_d_line} + _d_bks=($_d_bks ${_d_line[3]}) + fi + done >> $_d_file +bindkey | + while read -rA _d_line; do + if [[ ${_d_line[2]} = (${(j.|.)~_d_bks}) ]]; then + print -r "bindkey '${_d_line[1][2,-2]}' ${_d_line[2]}" + fi + done >> $_d_file + +print >> $_d_file + + +# Autoloads: whence -w produces "_d_foo: function", so look for +# all functions beginning with `_'. + +_d_als=($(whence -wm '_*' | sort | +while read -rA _d_line; do + [[ ${_d_line[2]} = function ]] && print -r - ${_d_line[1]%:} +done)) + +# print them out: about five to a line looks neat + +while (( $#_d_als )); do + print -n autoload + for (( _i = 0; _i < 5; _i++ )); do + if (( $#_d_als )); then + print -n " $_d_als[1]" + shift _d_als + fi + done + print +done >> $_d_file + +print >> $_d_file + +unset _d_line _d_zle _d_bks _d_als _d_f _f_file diff --git a/Completion/Core/compinit b/Completion/Core/compinit new file mode 100644 index 000000000..ec5867838 --- /dev/null +++ b/Completion/Core/compinit @@ -0,0 +1,269 @@ +# Initialisation for new style completion. This mainly contains some helper +# function and aliases. Everything else is split into different files in this +# directory that will automatically be made autoloaded (see the end of this +# file). +# The names of the files that will be considered for autoloading have to +# start with a underscores (like `_setopt). +# The first line of these files will be read and has to say what should be +# done with its contents: +# +# `#defcomp <names ...>' +# if the first line looks like this, the file is +# autoloaded as a function and that function will +# be called to generate the matches when completing +# for one of the commands whose <name> is given +# +# `#defpatcomp <pattern>' +# this defines a function that should be called to generate +# matches for commands whose name matches <pattern>; note +# that only one pattern may be given +# +# `#defkeycomp <style> [ <key-sequence> ... ] +# this is used to bind special completions to all the given +# <key-sequence>(s). The <style> is the name of one of the built-in +# completion widgets (complete-word, delete-char-or-list, +# expand-or-complete, expand-or-complete-prefix, list-choices, +# menu-complete, menu-expand-or-complete, or reverse-menu-complete). +# This creates a widget behaving like <style> so that the +# completions are chosen as given in the the rest of the file, +# rather than by the context. The widget has the same name as +# the autoload file and can be bound using bindkey in the normal way. +# +# `#autoload' +# this is for helper functions that are not used to +# generate matches, but should automatically be loaded +# when they are called +# +# Note that no white space is allowed between the `#' and the rest of +# the string. +# +# See the file `compdump' for how to speed up initialiation. +# +# If you are using global matching specifications with `compctl -M ...' +# have a look at the files `_match_test' and `_match_pattern'. To make +# all the example functions use matching as specified with `-M' these +# need some editing. +# +# If we got the `-d'-flag, we will automatically dump the new state (at +# the end). + +if [[ "$1" = -d ]]; then + _i_autodump=1 +else + _i_autodump=0 +fi + +# The associative array containing the definitions for the commands. +# Definitions for patterns will be stored in the normal array `_patcomps'. + +typeset -A _comps +_patcomps=() + +# This function is used to register or delete completion functions. For +# registering completion functions, it is invoked with the name of the +# function as it's first argument (after the options). The other +# arguments depend on what type of completion function is defined. If +# none of the `-p' and `-k' options is given a function for a command is +# defined. The arguments after the function name are then interpreted as +# the names of the command for which the function generates matches. +# With the `-p' option a function for a name pattern is defined. This +# function will be invoked when completing for a command whose name +# matches the pattern given as argument after the function name (in this +# case only one argument is accepted). +# With the `-k' option a function for a special completion keys is +# defined and immediatly bound to those keys. Here, the extra arguments +# are the name of one of the builtin completion widgets and any number +# of key specifications as accepted by the `bindkey' builtin. +# In any case the `-a' option may be given which makes the function +# whose name is given as the first argument be autoloaded. When defining +# a function for command names the `-n' option may be given and keeps +# the definitions from overriding any previous definitions for the +# commands. +# For deleting definitions, the `-d' option must be given. Without the +# `-p' option, this deletes definitions for functions for the commands +# whose names are given as arguments. If combined with the `-p' option +# it deletes the definitions for the patterns given as argument. +# The `-d' option may not be combined with the `-k' option, i.e. +# definitions for key function can not be removed. +# +# Examples: +# +# compdef -a foo bar baz +# make the completion for the commands `bar' and `baz' use the +# function `foo' and make this function be autoloaded +# +# compdef -p foo 'c*' +# make completion for all command whose name begins with a `c' +# generate matches by calling the function `foo' before generating +# matches defined for the command itself +# +# compdef -k foo list-choices '^X^M' '\C-xm' +# make the function `foo' be invoked when typing `Control-X Control-M' +# or `Control-X m'; the function should generate matches and will +# behave like the `list-choices' builtin widget +# +# compdef -d bar baz +# delete the definitions for the command names `bar' and `baz' + +compdef() { + local opt autol type func delete new i + + # Get the options. + + while getopts "anpkd" opt; do + case "$opt" in + a) autol=yes;; + n) new=yes;; + [pk]) if [[ -n "$type" ]]; then + # Error if both `-p' and `-k' are given (or one of them + # twice). + echo "$0: type already set to $type" + return 1 + fi + if [[ "$opt" = p ]]; then + type=pattern + else + type=key + fi + ;; + d) delete=yes;; + esac + done + shift OPTIND-1 + + if [[ -z "$delete" ]]; then + # Adding definitions, first get the name of the function name + # and probably do autoloading. + + func="$1" + [[ -n "$autol" ]] && autoload "$func" + shift + + case "$type" in + pattern) + if [[ $# -gt 1 ]]; then + echo "$0: only one pattern allowed" + return 1 + fi + # Patterns are stored in strings like `c* foo', with a space + # between the pattern and the function name. + + _patcomps=("$_patcomps[@]" "$1 $func") + ;; + key) + if [[ $# -lt 2 ]]; then + echo "$0: missing keys" + return 1 + fi + + # Define the widget. + zle -C "$func" "$1" "$func" + shift + + # And bind the keys... + for i; do + bindkey "$i" "$func" + done + ;; + *) + # For commands store the function name in the `_comps' + # associative array, command names as keys. + for i; do + [[ -z "$new" || "${+_comps[$i]}" -eq 0 ]] && _comps[$i]="$func" + done + ;; + esac + else + # Handle the `-d' option, deleting. + case "$type" in + pattern) + # Note the space. + for i; do + _patcomps=("${(@)patcomps:#$i *}") + done + ;; + key) + # Oops, cannot do that yet. + + echo "$0: cannot restore key bindings" + return 1 + ;; + *) + # Deleting definitons for command is even simpler. + for i; do + unset "_comps[$i]" + done + esac + fi +} + +# Now we automatically make the definition files autoloaded. + +# First we get the name of a dump file if this will be used. + +: ${COMPDUMP:=$0.dump} + +if [[ ! -o extendedglob ]]; then + _i_noextglob=yes + setopt extendedglob +fi + +typeset -U _i_files +_i_files=( ${^~fpath}/_*~*~(N:t) ) +_i_initname=$0 +_i_done='' + +# If we have a dump file, load it. + +if [[ -f "$COMPDUMP" ]]; then + read -rA _i_line < "$COMPDUMP" + if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files ]]; then + builtin . "$COMPDUMP" + _i_done=yes + fi + unset _i_line +fi +if [[ -z "$_i_done" ]]; then + for _i_dir in $fpath; do + [[ $_i_dir = . ]] && continue + for _i_file in $_i_dir/_*~*~(N); do + read -rA _i_line < $_i_file + _i_tag=$_i_line[1] + shift _i_line + if [[ $_i_tag = '#defcomp' ]]; then + compdef -na "${_i_file:t}" "${_i_line[@]}" + elif [[ $_i_tag = '#defpatcomp' ]]; then + compdef -pa "${_i_file:t}" "${_i_line[@]}" + elif [[ $_i_tag = '#defkeycomp' ]]; then + compdef -ka "${_i_file:t}" "${_i_line[@]}" + elif [[ $_i_tag = '#autoload' ]]; then + autoload ${_i_file:t} + fi + done + done + + bindkey | + while read -rA _i_line; do + if [[ "$_i_line[2]" = complete-word || + "$_i_line[2]" = delete-char-or-list || + "$_i_line[2]" = expand-or-complete || + "$_i_line[2]" = expand-or-complete-prefix || + "$_i_line[2]" = list-choices || + "$_i_line[2]" = menu-complete || + "$_i_line[2]" = menu-expand-or-complete || + "$_i_line[2]" = reverse-menu-complete ]]; then + zle -C _complete_$_i_line[2] $_i_line[2] _main_complete + bindkey "${_i_line[1][2,-2]}" _complete_$_i_line[2] + fi + done + + unset _i_dir _i_line _i_file _i_tag + + # If autodumping was requested, do it now. + + (( _i_autodump )) && builtin . ${_i_initname:h}/compdump +fi + +[[ -z "$_i_noextglob" ]] || unsetopt extendedglob + +unset _i_files _i_initname _i_done _i_autodump _i_noextglob diff --git a/Completion/README b/Completion/README new file mode 100644 index 000000000..ac2accfca --- /dev/null +++ b/Completion/README @@ -0,0 +1,107 @@ +The subdirectories contain code for the new function-based completion +system. Broadly speaking, this uses shell functions defined for each +command to determine how the arguments of a command should be completed. + +You should copy all the files you need or want to a directory of your own, +which should be included in your autoload path as defined by $fpath. Then +in your .zshrc you should source the file which appears here in +Core/compinit. It is recommnded that you use the -d option, which outputs +a file containing the necessary variables, bindkeys etc., making later +loading much faster. For example, + [[ -f ~/completion/compinit ]] && . ~/completion/compinit -d +This will rebind any keys which do completion to use the new system. +For more detailed instructions, including how to add new completions, see +the top of Core/compinit . + +The subdirectories contain: + +Core: + The basic functions and files to be sourced. You will certainly need + these, and will most likely not feel like altering them (or, in some + cases, even reading them, unless you are a shell wizard). The files are: + compinit + As already described, this is not a function, but is sourced once + (with the `source' or `.' commands) to set up the completion system. + compdump + This dumps the completions status for faster initialisation. The + easiest way of doing this is to use the -d option to compinit rather + than calling compdump directly. + _comp_parts + Utility used for completing words with multiple separate parts, such as + `<user>@<host>' + _compalso + Utility for calling a function to add additional completions to an + already existing set. + _files + A frontend to _path_files which will default to any old file if the + specified file was not found. + _main_complete + The main entry point called by the key bindings which compinit sets + up (the main `completion widget' in zsh jargon). + _normal + The function called by _main_complete to handle the most common + cases, such as completing a command name or its arguments. This + function dispatches to the various other functions for individual + commands. (Actually, the system is fairly context-sensitive, so + it is wider than just command+argument.) + _path_files + The function usually called to complete filenames and directories. It + replaces the standard -f and -/ options for the basic completion + commands: it can do various extra tricks, such as expanding a whole + path at once, e.g. F/C/C/_p<TAB> -> Functions/Completion/Core/_path_files +Base: + You will almost certainly want these files, too, which handle standard + tasks like completing files. However, you may want to edit them for + your own particular setup. Files are: + _command_names + This handles completion of the command word, i.e. the first thing + on the command line. You may want to alter this, for example, + to complete parameters to assign to. + _condition + This handles completing inside [[ ... ]] . + _default + This handles completion of command arguments when no special function + exists. Usually this means completing files, but you can modify this + as you wish. + _match_pattern + _match_test + These are used by Base/_path_files (and hence also Base/_files) for + file completion with control over matching (whether to complete + case-insensitively, or to allow insertion before `.', etc.) See + _match_test for instructions. Note _path_files expects these files + to be present. + _precommand + Allows completion when the first word on the line has to be ignored, + for example `noglob ...' should ignore the noglob and just complete + as if it wasn't there. Add other such commands to the top line. + _redirect + Completes after `<' or `<': this version calls _files. + _subscript + For completion in subscripts of parameters, e.g $foo[...]. + _vars + Completion for commands which need variables (so this could also be in + the Builtins directory), but also in math environments such as ((...)). +Builtins: + Define completions for various shell builtins. The top line of each file + says which builtins they apply to; in many cases you can guess from the + name. Note in particular that _zftp defines completions for all commands + beginning `zf', not just for the module command zftp. This is only + really useful if you use zftp with the zf* function suite (zfopen, zfget, + ...). +User: + This contains a pot pourri of completions for various external commands. + Not all will work unmodified on your system. +Commands: + These functions define separate completion commands which do not use + the usual context information, and hence have to be bound separately + to keys. As they appear, they have bindings which you can change or + delete by altering the top line of the file. To bind a function + (strictly speaking, the corresponding completion widget) yourself + after completion is loaded, use `bindkey '<key-string>' <_function_name>'. + The files are: + _correct_filename, bound to \C-xc + Correct the word under the cursor as a filename. This is significantly + more powerful than the standard \e$ (spell-word) binding. + _most_recent_file, bound to \C-xm + Insert the name of the most recent file matching the pattern + so far on the command line. diff --git a/Completion/User/_a2ps b/Completion/User/_a2ps new file mode 100644 index 000000000..9aa9d3d99 --- /dev/null +++ b/Completion/User/_a2ps @@ -0,0 +1,22 @@ +#defcomp a2ps + +if [[ -prefix -- ]]; then + _comp_parts '(--borders --compact --truncate-lines --interpret + --print-anyway --delegate)' '=' '(yes no)' + _comp_parts '(--major)' '=' '(rows columns)' + _comp_parts '(--end-of-line)' '=' '(r n nr rn any)' + + complist -S= -k '(--medium --columns --rows --line-numbers + --font-size --lines-per-page --chars-per-line + --tabsize --non-printable-format --encoding + --title --stdin --prologue --highlight-level + --strip-level --output --version-control --suffix + --printer --copies --sides --page-prefeed + --no-page-prefeed)' + complist -qS= -k '(--margin --header --underlay --left-title + --right-title --left-footer --footer --right-footer + --pages --pretty-print)' + complist -k '(--landscape --portrait --catman --no-header)' +else + _files -F fignore -g "*~*.ps" +fi diff --git a/Completion/User/_compress b/Completion/User/_compress new file mode 100644 index 000000000..860aeb5b0 --- /dev/null +++ b/Completion/User/_compress @@ -0,0 +1,3 @@ +#defcomp compress + +_files -g '*~*.Z' diff --git a/Completion/User/_configure b/Completion/User/_configure new file mode 100644 index 000000000..de8d5fba5 --- /dev/null +++ b/Completion/User/_configure @@ -0,0 +1,12 @@ +#defcomp configure + +if [[ $PREFIX = *=* ]]; then + # Complete filenames after e.g. --prefix= + IPREFIX=${PREFIX%%=*}= + PREFIX=${PREFIX#*=} + complist -f +else + # Generate a list of options from configure --help + complist -s '$($COMMAND --help | + sed -n -e '\''s/^ *\(--[-a-z0-9]*\)[ =,].*$/\1/p'\'')' +fi diff --git a/Completion/User/_dd b/Completion/User/_dd new file mode 100644 index 000000000..2458541ea --- /dev/null +++ b/Completion/User/_dd @@ -0,0 +1,13 @@ +#defcomp dd + +if [[ -iprefix conv= ]]; then + # If there's a comma present, ignore up to the last one. The + # test alone will have that effect. + [[ -string , ]] + complist -S, -q \ + -k '(ascii ebcdic ibm block unblock lcase ucase swab noerror sync)' +elif [[ -iprefix 'if=' || -iprefix 'of=' ]]; then + _files +else + complist -S '=' -k '(if of ibs obs bs cbs skip files seek count conv)' +fi diff --git a/Completion/User/_dvi b/Completion/User/_dvi new file mode 100644 index 000000000..bb2fc293e --- /dev/null +++ b/Completion/User/_dvi @@ -0,0 +1,3 @@ +#defcomp xdvi dvips dvibook dviconcat dvicopy dvidvi dviselect dvitodvi dvitype + +_files -g '*.(dvi|DVI)' diff --git a/Completion/User/_find b/Completion/User/_find new file mode 100644 index 000000000..ca4f79908 --- /dev/null +++ b/Completion/User/_find @@ -0,0 +1,21 @@ +#defcomp find + +if [[ -mbetween -(ok|exec) \\\; ]]; then + _normal "$@" +elif [[ -iprefix - ]]; then + complist -s 'daystart {max,min,}depth follow noleaf version xdev \ + {a,c,}newer {a,c,m}{min,time} empty false {fs,x,}type gid inum links \ + {i,}{l,}name {no,}{user,group} path perm regex size true uid used \ + exec {f,}print{f,0,} ok prune ls' +elif [[ -position 1 ]]; then + complist -g '. ..' + _files -g '(-/)' +elif [[ -mcurrent -1 -((a|c|)newer|fprint(|0|f)) ]]; then + _files +elif [[ -current -1 -fstype ]]; then + complist -k '(ufs 4.2 4.3 nfs tmp mfs S51K S52K)' +elif [[ -current -1 -group ]]; then + complist -k groups +elif [[ -current -1 -user ]]; then + complist -u +fi diff --git a/Completion/User/_gunzip b/Completion/User/_gunzip new file mode 100644 index 000000000..35a27e774 --- /dev/null +++ b/Completion/User/_gunzip @@ -0,0 +1,3 @@ +#defcomp gunzip zcat + +_files -g '*.[gG][z]' diff --git a/Completion/User/_gzip b/Completion/User/_gzip new file mode 100644 index 000000000..3cda1e4ed --- /dev/null +++ b/Completion/User/_gzip @@ -0,0 +1,3 @@ +#defcomp gzip + +_files -g '*~*.[gG][zZ]' diff --git a/Completion/User/_hosts b/Completion/User/_hosts new file mode 100644 index 000000000..3acc327ac --- /dev/null +++ b/Completion/User/_hosts @@ -0,0 +1,3 @@ +#defcomp ftp ncftp ping rwho rup xping traceroute nslookup + +complist -k hosts diff --git a/Completion/User/_make b/Completion/User/_make new file mode 100644 index 000000000..d576b0308 --- /dev/null +++ b/Completion/User/_make @@ -0,0 +1,3 @@ +#defcomp make gmake pmake + +complist -s "\$(awk '/^[a-zA-Z0-9][^/ ]+:/ {print \$1}' FS=: [mM]akefile)" diff --git a/Completion/User/_man b/Completion/User/_man new file mode 100644 index 000000000..8204fba0b --- /dev/null +++ b/Completion/User/_man @@ -0,0 +1,11 @@ +#defcomp man +setopt localoptions rcexpandparam + +local rep +if [[ $2 = (<->*|ln) ]]; then + rep=( $manpath/(man|cat)$2/$PREFIX*$SUFFIX.<->*(N:t:r) ) +else + rep=( $manpath/(man|cat)*/$PREFIX*$SUFFIX.<->*(N:t:r) ) +fi + +(( $#rep )) && compadd -m $rep diff --git a/Completion/User/_mh b/Completion/User/_mh new file mode 100644 index 000000000..67ce49fd2 --- /dev/null +++ b/Completion/User/_mh @@ -0,0 +1,70 @@ +#defcomp folder comp inc mark refile repl scan show next prev rmm pick whom mhn mhpath mhpatch + +# Completion for all possible MH commands. +# Alter the following two to your own mh directory and the directory +# where standard mh library files live. (It works anyway, but this +# will save a little time.) +local mymhdir=~/Mail +local mhlib=/usr/lib/mh + +# To be on the safe side, check this exists and if not, get it anyway. +[[ -d $mymhdir ]] || mymhdir=$(mhpath +) + +if [[ -iprefix - ]]; then + # get list of options, which MH commands can generate themselves + # awk is just too icky to use for this, sorry. send me one if + # you come up with it. + compadd -m $($COMMAND -help | perl -ne 'if (/^\s*-\(?(\S+)/) { + $n = $1; + $n =~ s/\)//g; + print $n =~ s/^\[([a-z]+)\]// ? "$n\n$1$n\n" : "$n\n"; + }') + return +elif [[ -iprefix '+' || -iprefix '@' || -current -1 -draftfolder ]]; then + # Complete folder names. + local mhpath + if [[ $IPREFIX != '@' ]]; then + [[ $IPREFIX = '+' ]] || IPREFIX=+ + mhpath=$mymhdir + else + mhpath=$(mhpath) + fi + + # painless, or what? + complist -W mhpath -/ +elif [[ -mcurrent -1 -(editor|(whatnow|rmm|show|more)proc) ]]; then + complist -c +elif [[ -current -1 -file ]]; then + complist -f +elif [[ -mcurrent -1 -(form|audit|filter) ]]; then + # Need some MH template file, which may be in our own MH directory + # or with the standard library. + local mhfpath + # This is the only place we need mhlib, so leave the test till here. + [[ -d $mhlib ]] || { mhlib=$(mhparam mhlproc); mhlib=$mhlib:h; } + mhfpath=($mymhdir $mhlib) + + complist -W mhfpath -g '*(.)' +elif [[ -mcurrent -1 -(no|)cc ]]; then + compadd -m all to cc me +elif [[ -mcurrent -1 -[rw]cache ]]; then + compadd -m public private never ask +else + # Generate sequences. + local foldnam folddir f + for f in $argv; do + [[ $f = [@+]* ]] && foldnam=$f + done + if [[ $foldnam = '+'* ]]; then + folddir=$mymhdir/${foldnam#+} + elif [[ $foldnam = '@'* ]]; then + folddir=$(mhpath)/${foldnam#@} + else + folddir=$(mhpath) + # leaving foldnam empty works here + fi + + complist -s '$(mark $foldnam | awk -F: '\''{ print $1 }'\'')' + compadd -m reply next cur prev first last all unseen + complist -W folddir -g '<->' +fi diff --git a/Completion/User/_pdf b/Completion/User/_pdf new file mode 100644 index 000000000..7d7756c3e --- /dev/null +++ b/Completion/User/_pdf @@ -0,0 +1,3 @@ +function acroread + +_files -g '*.(pdf|PDF)' diff --git a/Completion/User/_ps b/Completion/User/_ps new file mode 100644 index 000000000..6bc0643b2 --- /dev/null +++ b/Completion/User/_ps @@ -0,0 +1,3 @@ +#defcomp gs ghostview gview psnup psselect pswrap pstops pstruct lpr + +_files -g '*([pP][sS]|eps)' diff --git a/Completion/User/_rcs b/Completion/User/_rcs new file mode 100644 index 000000000..537db6278 --- /dev/null +++ b/Completion/User/_rcs @@ -0,0 +1,9 @@ +#defcomp co ci rcs + +[[ $COMMAND = ci || $COMMAND = rcs ]] && _files + +if [[ $NMATCHES -eq 0 && -d RCS && $COMMAND != ci ]]; then + local rep + rep=(RCS/$PREFIX*$SUFFIX,v(:t:s/\,v//)) + (( $#rep )) && compadd -m $rep +fi diff --git a/Completion/User/_rlogin b/Completion/User/_rlogin new file mode 100644 index 000000000..e36554f23 --- /dev/null +++ b/Completion/User/_rlogin @@ -0,0 +1,9 @@ +#defcomp rlogin rsh ssh + +if [[ -position 1 ]]; then + complist -k hosts +elif [[ -position 2 ]]; then + complist -k '(-l)' +else + complist -u +fi diff --git a/Completion/User/_strip b/Completion/User/_strip new file mode 100644 index 000000000..6962ac455 --- /dev/null +++ b/Completion/User/_strip @@ -0,0 +1,2 @@ +#defcomp strip +_files -g '*(*)' diff --git a/Completion/User/_stty b/Completion/User/_stty new file mode 100644 index 000000000..6b54b5007 --- /dev/null +++ b/Completion/User/_stty @@ -0,0 +1,16 @@ +#defcomp stty + +if [[ -mcurrent -1 \ + (*erase|discard|status|dsusp|intr|kill|lnext|quit|reprint|start|s*p) ]] +then + compadd -m -Q '^-' '^h' '^?' '^c' '^u' +else + [[ -string '-' || -string '+' ]] + compadd -m rows columns intr quit erase kill eof eol \ + eol2 start stop susp dsusp reprint discard werase lnext \ + parenb parodd cs8 cstopb hupcl cread clocal parext \ + ignbrk brkint ignpar parmrk inpck istrip inlcr igncr icrnl iuclc \ + ixon ixany ixoff imaxbel isig icanon xcase echo echoe echok \ + echonl noflsh tostop echoctl echoprt echoke flusho pending iexten \ + opost olcuc onlcr ocrnl onocr onlret ofill ofdel +fi diff --git a/Completion/User/_tar b/Completion/User/_tar new file mode 100644 index 000000000..91767e44d --- /dev/null +++ b/Completion/User/_tar @@ -0,0 +1,11 @@ +#defcomp tar + +local nm=$NMATCHES tf="$2" + +if [[ ( -mword 1 *t*f* || -mword 1 *x*f* ) && -position 3 100000 ]]; then + complist -k "( $(tar tf $tf) )" +elif [[ -mword 1 *c*f* && -position 3 100000 ]]; then + _files +elif [[ -mcurrent -1 *f* && -position 2 ]]; then + _files -g '*.(tar|TAR)' +fi diff --git a/Completion/User/_tex b/Completion/User/_tex new file mode 100644 index 000000000..1f645e2a2 --- /dev/null +++ b/Completion/User/_tex @@ -0,0 +1,3 @@ +#defcomp tex latex slitex + +_files -g '*.(tex|TEX|texinfo|texi)' diff --git a/Completion/User/_uncompress b/Completion/User/_uncompress new file mode 100644 index 000000000..e25805d50 --- /dev/null +++ b/Completion/User/_uncompress @@ -0,0 +1,3 @@ +#defcomp uncompress zmore + +_files -g '*.Z' diff --git a/Completion/User/_x_options b/Completion/User/_x_options new file mode 100644 index 000000000..cc469286d --- /dev/null +++ b/Completion/User/_x_options @@ -0,0 +1,5 @@ +#defpatcomp */X11/* + +# A simple pattern completion, just as an example. + +complist -J options -k '(-display -name -xrm)' diff --git a/Completion/User/_xfig b/Completion/User/_xfig new file mode 100644 index 000000000..fcd2bba9f --- /dev/null +++ b/Completion/User/_xfig @@ -0,0 +1,3 @@ +#defcomp xfig + +_files -g '*.fig' |