1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-05-04 22:56:18 +02:00

Initial revision

This commit is contained in:
Tanaka Akira 1999-04-15 18:05:38 +00:00
parent c175751b50
commit e74702b467
354 changed files with 66043 additions and 0 deletions

3
Completion/.distfiles Normal file
View File

@ -0,0 +1,3 @@
DISTFILES_SRC='
.distfiles README
'

View File

@ -0,0 +1,6 @@
DISTFILES_SRC='
.distfiles
_brace_parameter _command_names _condition _default _equal
_long_options _match_pattern _match_pattern.orig _match_test _parameter
_precommand _redirect _subscript _tilde _vars
'

View File

@ -0,0 +1,5 @@
#defcomp -brace-parameter-
# Simple but without spiffy suffix handling: compgen -v -S '} '
compadd -S '} ' -r '-:?#%+=[/' - "${(@)${${${(f)$(typeset)}%%\=*}##* }:gs/'//}"

View File

@ -0,0 +1,3 @@
#defcomp -command-
complist -c

View File

@ -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

13
Completion/Base/_default Normal file
View File

@ -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

3
Completion/Base/_equal Normal file
View File

@ -0,0 +1,3 @@
#defcomp -equal-
compgen -am

View File

@ -0,0 +1,309 @@
#autoload
# This function tries to automatically complete long option names. For
# this it invokes the command from the line with the `--help' option
# and then parses the output to find possible option names. For
# options that get an argument after a `=', the function also tries to
# automatically find out what should be complete as the argument.
# The possible completions for option-arguments can be described with
# the arguments to this function. This is done by giving pairs of
# patterns and actions as consecutive arguments. The actions specify
# what should be done to complete arguemts of those options that match
# the pattern. The action may be a list of words in brackets or in
# parentheses, separated by spaces. A list in brackets denotes
# possible values for an optional argument, a list in parentheses
# gives words to complete for mandatory arguments. If the action does
# not start with a bracket or parentheses, it should be the name of a
# command (probably with arguments) that should be invoked to complete
# after the equal sign. E.g.:
#
# _long_options '*\*' '(yes no)' \
# '*=FILE*' '_files' \
# '*=DIR*' '_files -/'
#
# This makes `yes' and `no' be completed as the argument of options
# whose description ends in a star, file names for options that
# contain the substring `=FILE' in the description, and paths for
# options whose description contains `=DIR'. Note the last two
# patterns are not needed since this function always completes files
# for option descriptions containing `=FILE' and paths for option
# descriptions that contain `=DIR' or `=PATH'. These builtin patterns
# can be overridden by patterns given as arguments, though.
#
# This function also accepts the `-X', `-J', and `-V' options which
# are given to `compadd'. Finally, it accepts the option `-t'. If this
# is given, completion is only done on words starting with two hyphens.
local opt expl group test i name action ret=1 tmp suffix
setopt extendedglob
# Get the options.
group=()
expl=()
if [[ $1 = -*~--* ]]; then
while getopts "J:V:X:t" opt; do
case "$opt" in
[JV]) group=("-$opt" "$OPTARG");;
X) expl=(-X "$OPTARG");;
t) test=yes;;
esac
done
shift OPTIND-1
fi
# Test if we are completing after `--' if we were asked to do so.
[[ -n "$test" && "$PREFIX" != --* ]] && return 1
# We cache the information about options and the command name, see if
# we can use the cache.
if [[ "$words[1]" = (.|..)/* ]]; then
tmp="$PWD/$words[1]"
else
tmp="$words[1]"
fi
if [[ "$tmp" != $_lo_cache_cmd ]]; then
# No, store the new command name and clear the old parameters.
_lo_cache_cmd="$tmp"
(( $+_lo_cache_actions )) && unset "$_lo_cache_names[@]" _lo_cache_actions _lo_cache_names
local opts pattern anum=1 tmpo str
# Now get the long option names by calling the command with `--help'.
# The parameter expansion trickery first gets the lines as separate
# array elements. Then we select all lines whose first non-blank
# character is a hyphen. Since some commands document more than one
# option per line, separated by commas, we convert commas int
# newlines and then split the result again at newlines after joining
# the old array elements with newlines between them. Then we select
# those elements that start with two hyphens, remove anything up to
# those hyphens and anything from the space or comma after the
# option up to the end. Finally all elements with option strings
# that contain uppercase letters are removed.
opts=("--${(@)^${(@)${(@)${(@M)${(@ps:\n:j:\n:)${(@)${(@M)${(@f)$("$words[1]" --help)}:#[ ]#-*}//,/
}}:#[ ]#--*}#*--}%%[, ]*}:#(*-[A-Z]*|)}")
# The interpretation of the options is completely table driven. We
# use the positional parameters we were given and a few standard
# ones. Then we loop through this table.
set -- "$@" '*=FILE*' '_files' '*=(DIR|PATH)*' '_files -/' '*' ''
while [[ $# -gt 1 ]]; do
# First, we get the pattern and the action to use and take them
# from the positional parameters.
pattern="$1"
action="$2"
shift 2
# We get all options matching the pattern and take them from the
# list we have built. If no option matches the pattern, we
# continue with the next.
tmp=("${(@M)opts:##$~pattern}")
opts=("${(@)opts:##$~pattern}")
(( $#tmp )) || continue
# Now we collect the options for the pattern in an array. We also
# check if the options take an argument after a `=', and if this
# argument is optional. The name of the array built contains
# `_arg_' for mandatory arguments, `_optarg_' for optional
# arguments, and `_simple_' for options that don't get an
# argument. In `_lo_cache_names' we save the names of these
# arrays and in `_lo_cache_actions' the associated actions.
# If the action is a list of words in brackets, this denotes
# options that get an optional argument. If the action is a list
# of words in parentheses, the option has to get an argument.
# In both cases we just build the array name to use.
if [[ "$action[1]" = '[' ]]; then
name="_lo_cache_optarg_$anum"
elif [[ "$action[1]" = '(' ]]; then
name="_lo_cache_arg_$anum"
else
# If there are option strings with a `[=', we take make these
# get an optional argument...
tmpo=("${(@M)tmp:#*\[\=*}")
if (( $#tmpo )); then
# ...by removing them from the option list and storing them in
# an array.
tmp=("${(@)tmp:#*\[\=*}")
tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
_lo_cache_names[anum]="_lo_cache_optarg_$anum"
_lo_cache_actions[anum]="$action"
eval "_lo_cache_optarg_${anum}=(\"\$tmpo[@]\")"
(( anum++ ))
fi
# Now we do the same for option strings containing `=', these
# are options getting an argument.
tmpo=("${(@M)tmp:#*\=*}")
if (( $#tmpo )); then
tmp=("${(@)tmp:#*\=*}")
tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
_lo_cache_names[anum]="_lo_cache_arg_$anum"
_lo_cache_actions[anum]="$action"
eval "_lo_cache_arg_${anum}=(\"\$tmpo[@]\")"
(( anum++ ))
fi
# The name for the options without arguments, if any.
name="_lo_cache_simple_$anum"
fi
# Now filter out any option strings we don't like and stuff them
# in an array, if there are still some.
tmp=("${(@)${(@)tmp%%\=*}//[^a-z0-9-]}")
if (( $#tmp )); then
_lo_cache_names[anum]="$name"
_lo_cache_actions[anum]="$action"
eval "${name}=(\"\$tmp[@]\")"
(( anum++ ))
fi
done
fi
# We get the string from the line and and see if it already contains a
# equal sign.
str="$PREFIX$SUFFIX"
if [[ "$str" = *\=* ]]; then
# It contains a `=', now we ignore anything up to it, but first save
# the old contents of the special parameters we change.
local oipre opre osuf pre parto parta pat patflags anum=1
oipre="$IPREFIX"
opre="$PREFIX"
osuf="$SUFFIX"
pre="${str%%\=*}"
IPREFIX="${IPREFIX}${pre}="
PREFIX="${str#*\=}"
SUFFIX=""
# We will check if the arrays contain an option matching what's on
# the line. To do this good, we build a pattern.
[[ -n "$_comp_correct" && $#pre -le _comp_correct ]] && return 1
pat="${pre}*"
patflags=''
_match_pattern _long_options pat patflags
[[ -n "$_comp_correct" ]] && patflags="$patflags(#a$_comp_correct)"
# Then we walk through the array names. For each array we test if it
# contains the option string. If so, we `invoke' the action stored
# with the name. If the action is a list of words, we just add them,
# otherwise we invoke the command or function named.
for name in "$_lo_cache_names[@]"; do
action="$_lo_cache_actions[anum]"
if (( ${(@)${(@P)name}[(I)$pre]} )); then
if [[ "$action[1]" = (\[|\() ]]; then
compadd - ${=action[2,-2]}
elif (( $#action )); then
$=action
fi
# We found the option string, return.
return
fi
# The array did not contain the full option string, see if it
# contains a string matching the string from the line.
# If there is one, we store the option string in `parto' and the
# element from `_lo_actions' in `parta'. If we find more than one
# such option or if we already had one, we set `parto' to `-'.
tmp=("${(@M)${(@P)name}:#${~pat}}")
if [[ $#tmp -eq 1 ]]; then
if [[ -z "$parto" ]]; then
parto="$tmp[1]"
parta="$action"
else
parto=-
fi
elif (( $#tmp )); then
parto=-
fi
(( anum++ ))
done
# If we found only one matching option, we accept it and immediatly
# try to complete the string after the `='.
if [[ -n "$parto" && "$parto" != - ]]; then
IPREFIX="${parto}="
if (( $#parta )); then
if [[ "$parta[1]" = (\[|\() ]]; then
compadd - ${=parta[2,-2]}
else
$=parta
fi
else
compadd -S '' - "$PREFIX"
fi
return
fi
# The option string was not found, restore the special parameters.
IPREFIX="$oipre"
PREFIX="$opre"
SUFFIX="$osuf"
fi
# The string on the line did not contain a `=', or we couldn't
# complete the option string since there were more than one matching
# what's on the line. So we just ad the option string as possible
# matches, giving the string from the `=' on as a suffix.
if [[ "$str" = *\=* ]]; then
str="=${str#*\=}"
PREFIX="${PREFIX%%\=*}"
suffix=()
else
str=""
suffix=('-S=')
fi
anum=1
for name in "$_lo_cache_names[@]"; do
action="$_lo_cache_actions[anum]"
if [[ "$name" = *_optarg_* ]]; then
compadd -M 'r:|-=* r:|=*' -Qq "$suffix[@]" -s "$str" - \
"${(@P)name}" && ret=0
elif [[ "$name" = *_arg_* ]]; then
compadd -M 'r:|-=* r:|=*' -Q "$suffix[@]" -s "$str" - \
"${(@P)name}" && ret=0
elif [[ -z "$str" ]]; then
compadd -M 'r:|-=* r:|=*' -Q - \
"${(@P)name}" && ret=0
fi
(( anum++ ))
done
return ret

View File

@ -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.

View File

@ -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 ))

18
Completion/Base/_math Normal file
View File

@ -0,0 +1,18 @@
#defcomp -math-
if [[ "$PREFIX" = *[^a-zA-Z0-9_]* ]]; then
IPREFIX="$IPREFIX${PREFIX%%[a-zA-Z0-9_]#}"
PREFIX="${PREFIX##*[^a-zA-Z0-9_]}"
fi
if [[ "$SUFFIX" = *[^a-zA-Z0-9_]* ]]; then
ISUFFIX="${SUFFIX##[a-zA-Z0-9_]#}$ISUFFIX"
SUFFIX="${SUFFIX%%[^a-zA-Z0-9_]*}"
fi
compgen -v
#defcomp -math-
IPREFIX="$IPREFIX${PREFIX%[a-zA-Z0-9_]*}"
PREFIX="${PREFIX##*[^a-zA-Z0-9_]}"
compgen -v

View File

@ -0,0 +1,3 @@
#defcomp -parameter-
compgen -v

View File

@ -0,0 +1,5 @@
#defcomp - nohup nice eval time rusage noglob nocorrect exec
[[ -position 1 -1 ]]
_normal "$@"

View File

@ -0,0 +1,3 @@
#defcomp -redirect-
_files

View File

@ -0,0 +1,4 @@
#defcomp -subscript-
_compalso -math- "$@"
[[ ${(Pt)${COMMAND}} = assoc* ]] && complist -k "( ${(kP)${COMMAND}} )"

10
Completion/Base/_tilde Normal file
View File

@ -0,0 +1,10 @@
#defcomp -tilde-
# We use all named directories and user names here. If this is too slow
# for you or if there are too many of them, you may want to use
# `compgen -k friends -qS/' or something like that. To get all user names
# if there are no matches in the `friends' array, add
# `(( compstate[nmatches] )) || compgen -nu -qS/'
# below that.
compgen -nu -qS/

3
Completion/Base/_vars Normal file
View File

@ -0,0 +1,3 @@
#defcomp -math- getopts read unset vared
complist -v

View File

@ -0,0 +1,7 @@
DISTFILES_SRC='
.distfiles
_aliases _arrays _autoload _bg_jobs _bindkey _builtin _cd _command
_dirs _disable _echotc _enable _fc _functions _hash _jobs _kill
_limits _sched _set _setopt _source _trap _unhash _unsetopt _vars_eq
_wait _which _zftp _zle _zmodload
'

View File

@ -0,0 +1,3 @@
#defcomp unalias
complist -a

View File

@ -0,0 +1,3 @@
#defcomp shift
complist -A

View File

@ -0,0 +1,3 @@
#defcomp autoload
complist -s '${^fpath}/*(N:t)'

View File

@ -0,0 +1,3 @@
#defcomp bg
complist -z -P '%'

View File

@ -0,0 +1,7 @@
#defcomp bindkey
if [[ -mword 1 -*[DAN]* || -mcurrent -1 -*M ]]; then
complist -s '$(bindkey -l)'
else
complist -b
fi

View File

@ -0,0 +1,7 @@
#defcomp builtin
if [[ -position 2 -1 ]]; then
_normal "$@"
else
complist -eB
fi

3
Completion/Builtins/_cd Normal file
View File

@ -0,0 +1,3 @@
#defcomp cd
_files -W cdpath -g '*(-/)'

View File

@ -0,0 +1,7 @@
#defcomp command
if [[ -position 2 -1 ]]; then
_normal "$@"
else
complist -em
fi

View File

@ -0,0 +1,3 @@
#defcomp rmdir df du dircmp
_files -/

View File

@ -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

View File

@ -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)'

View File

@ -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

7
Completion/Builtins/_fc Normal file
View File

@ -0,0 +1,7 @@
#defcomp fc
if [[ -mcurrent -1 -*e ]]; then
complist -c
elif [[ -mcurrent -1 -[ARWI]## ]]; then
_files
fi

View File

@ -0,0 +1,3 @@
#defcomp unfunction
complist -F

13
Completion/Builtins/_hash Normal file
View File

@ -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

View File

@ -0,0 +1,3 @@
#defcomp fg jobs
complist -j -P '%'

11
Completion/Builtins/_kill Normal file
View File

@ -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

View File

@ -0,0 +1,3 @@
#defcomp limit unlimit
complist -k "(${(j: :)${(f)$(limit)}%% *})"

View File

@ -0,0 +1,3 @@
#defcomp sched
[[ -position 2 -1 ]] && _normal "$@"

7
Completion/Builtins/_set Normal file
View File

@ -0,0 +1,7 @@
#defcomp set
if [[ -mcurrent -1 [-+]o ]]; then
complist -o
elif [[ -current -1 -A ]]; then
complist -A
fi

View File

@ -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

View File

@ -0,0 +1,7 @@
#defcomp source
if [[ -position 2 -1 ]]; then
_normal "$@"
else
_files
fi

View File

@ -0,0 +1,7 @@
#defcomp trap
if [[ -position 1 ]]; then
complist -c
else
complist -k signals
fi

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
#defcomp declare export integer local readonly typeset
complist -v -q -S '='

View File

@ -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`'

View File

@ -0,0 +1,3 @@
#defcomp which whence where type
complist -caF

50
Completion/Builtins/_zftp Normal file
View File

@ -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

7
Completion/Builtins/_zle Normal file
View File

@ -0,0 +1,7 @@
#defcomp zle
if [[ -word 1 -N && -position 3 ]]; then
complist -F
else
complist -b
fi

View File

@ -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

View File

@ -0,0 +1,3 @@
DISTFILES_SRC='
.distfiles _correct_filename _most_recent_file
'

View File

@ -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

View File

@ -0,0 +1,12 @@
#compdef -k complete-word \C-xc
# Simple completion front-end implementing spelling correction.
# The maximum number of errors is set quite high, and
# the numeric prefix can be used to specify a different value.
local oca="$compconfig[correct_accept]"
compconfig[correct_accept]=6n
_main_complete _correct
compconfig[correct_accept]=$oca

View File

@ -0,0 +1,4 @@
#defkeycomp complete-word \C-xm
local file
file=($~PREFIX*$~SUFFIX(om[1]N))
(( $#file )) && compadd -f $file

View File

@ -0,0 +1,5 @@
DISTFILES_SRC='
.distfiles
_compalso _files _main_complete _multi_parts _normal _path_files
_sep_parts compdump compinit
'

View File

@ -0,0 +1,197 @@
#autoload
# This code will try to correct the string on the line based on the
# strings generated for the context if `compconfig[correct]' is set.
# These corrected strings will be shown in a list and one can
# cycle through them as in a menucompletion or get the corrected prefix.
#
# Supported configuration keys:
#
# approximate_accept
# This should be set to a number, specifying the maximum number
# of errors that should be accepted. If the string also contains
# a `n' or `N', the code will use the numeric argument as the
# maximum number of errors if a numeric argument was given. If no
# numeric argument was given, the number from the value of this
# key will be used. E.g. with `compconf approximate_accept=2n' two
# errors will be accepted, but if the user gives another number
# with the numeric argument, this will be prefered. Also, with
# `compconf approximate_accept=0n', normally no correction will be
# tried, but if a numeric argument is given, automatic correction
# will be used. On the other hand, if the string contains an `!'
# and a `n' or `N', correction is not attempted if a numeric
# argument is given. Once the number of errors to accept is
# determined, the code will repeatedly try to generate matches by
# allowing one error, two errors, and so on. Independent of the
# number of errors the user wants to accept, the code will allow
# only fewer errors than there are characters in the string from
# the line.
#
# approximate_original
# This value is used to determine if the original string should
# be included in the list (and thus be presented to the user when
# cycling through the corrections). If it is set to any non-empty
# value, the original string will be offered. If it contains the
# sub-string `last', the original string will appear as the last
# string when cycling through the corrections, otherwise it will
# appear as the first one (so that the command line does not
# change immediately). Also, if the value contains the sub-string
# `always', the original string will always be included, whereas
# normally it is included only if more than one possible
# correction was generated.
#
# approximate_prompt
# This can be set to a string that should be printed before the
# list of corrected strings when cycling through them. This string
# may contain the control sequences `%n', `%B', etc. known from
# the `-X' option of `compctl'. Also, the sequence `%e' will be
# replaced by the number of errors accepted to generate the
# corrected strings.
#
# approximate_insert
# If this is set to a string starting with `unambig', the code
# will try to insert a usable unambiguous string in the command
# line instead of always cycling through the corrected strings.
# If such a unambiguous string could be found, the original
# string is not used, independent of the setting of
# `approximate_original'. If no sensible string could be found,
# one can cycle through the corrected strings as usual.
#
# If any of these keys is not set, but the the same key with the
# prefix `correct' instead of `approximate' is set, that value will
# be used.
local _comp_correct _correct_prompt comax
local cfgacc cfgorig cfgps cfgins
# Only if all global matchers hav been tried.
[[ compstate[matcher] -ne compstate[total_matchers] ]] && return 1
# We don't try correction if the string is too short.
[[ "${#:-$PREFIX$SUFFIX}" -le 1 ]] && return 1
# Get the configuration values, using either the prefix `correct' or
# `approximate'.
if [[ "$compstate[pattern_match]" = (|\**) ]]; then
cfgacc="${compconfig[approximate_accept]:-$compconfig[correct_accept]}"
cfgorig="${compconfig[approximate_original]:-$compconfig[correct_original]}"
cfgps="${compconfig[approximate_prompt]:-$compconfig[correct_prompt]}"
cfgins="${compconfig[approximate_insert]:-$compconfig[correct_insert]}"
else
cfgacc="$compconfig[correct_accept]"
cfgorig="$compconfig[correct_original]"
cfgps="$compconfig[correct_prompt]"
cfgins="$compconfig[correct_insert]"
fi
# Get the number of errors to accept.
if [[ "$cfgacc" = *[nN]* && NUMERIC -ne 1 ]]; then
# Stop if we also have a `!'.
[[ "$cfgacc" = *\!* ]] && return 1
# Prefer the numeric argument if that has a sensible value.
comax="$NUMERIC"
else
comax="${cfgacc//[^0-9]}"
fi
# If the number of errors to accept is too small, give up.
[[ "$comax" -lt 1 ]] && return 1
# Otherwise temporarily define functions to use instead of
# the builtins that add matches. This is used to be able
# to stick the `(#a...)' into the right place (after an
# ignored prefix).
compadd() {
[[ "$*" != *-([a-zA-Z/]#|)U* &&
"${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return
if [[ "$PREFIX" = \~*/* ]]; then
PREFIX="${PREFIX%%/*}/(#a${_comp_correct})${PREFIX#*/}"
else
PREFIX="(#a${_comp_correct})$PREFIX"
fi
if [[ -n "$_correct_prompt" ]]; then
builtin compadd -X "$_correct_prompt" -J _correct "$@"
else
builtin compadd -J _correct "$@"
fi
}
compgen() {
[[ "$*" != *-([a-zA-Z/]#|)U* &&
"${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return
if [[ "$PREFIX" = \~*/* ]]; then
PREFIX="${PREFIX%%/*}/(#a${_comp_correct})${PREFIX#*/}"
else
PREFIX="(#a${_comp_correct})$PREFIX"
fi
if [[ -n "$_correct_prompt" ]]; then
builtin compgen "$@" -X "$_correct_prompt" -J _correct
else
builtin compgen "$@" -J _correct
fi
}
# Now initialise our counter. We also set `compstate[matcher]'
# to `-1'. This allows completion functions to use the simple
# `[[ compstate[matcher] -gt 1 ]] && return' to avoid being
# called for multiple global match specs and still be called
# again when correction is done. Also, this makes it easy to
# test if correction is attempted since `compstate[matcher]'
# will never be set to a negative value by the completion code.
_comp_correct=1
compstate[matcher]=-1
_correct_prompt="${cfgps//\%e/1}"
# We also need to set `extendedglob' and make the completion
# code behave as if globcomplete were set.
setopt extendedglob
[[ -z "$compstate[pattern_match]" ]] && compstate[pattern_match]='*'
while [[ _comp_correct -le comax ]]; do
if _complete; then
if [[ "$cfgins" = unambig* &&
"${#compstate[unambiguous]}" -ge "${#:-$PREFIX$SUFFIX}" ]]; then
compstate[pattern_insert]=unambiguous
elif [[ compstate[nmatches] -gt 1 || "$cfgorig" = *always* ]]; then
if [[ "$cfgorig" = *last* ]]; then
builtin compadd -U -V _correct_original -nQ - "$PREFIX$SUFFIX"
elif [[ -n "$cfgorig" ]]; then
builtin compadd -U -nQ - "$PREFIX$SUFFIX"
fi
# If you always want to see the list of possible corrections,
# set `compstate[list]=list' here.
compstate[force_list]=list
fi
compstate[matcher]="$compstate[total_matchers]"
unfunction compadd compgen
return 0
fi
[[ "${#:-$PREFIX$SUFFIX}" -le _comp_correct+1 ]] && break
(( _comp_correct++ ))
_correct_prompt="${cfgps//\%e/$_comp_correct}"
done
compstate[matcher]="$compstate[total_matchers]"
unfunction compadd compgen
return 1

147
Completion/Core/_comp_parts Normal file
View File

@ -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

13
Completion/Core/_compalso Normal file
View File

@ -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" "$@"

52
Completion/Core/_complete Normal file
View File

@ -0,0 +1,52 @@
#autoload
# Generate all possible completions. Note that this is not intended as
# a normal completion function, but as one possible value for the
# compconfig[completer] parameter.
local comp name
# 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
(( compstate[nmatches] ))
return
fi
fi
# For arguments and command names we use the `_normal' function.
if [[ "$compstate[context]" = command ]]; then
_normal
else
# Let's see if we have a special completion definition for the other
# possible contexts.
comp=''
case $compstate[context] in
equal) comp="$_comps[-equal-]";;
tilde) comp="$_comps[-tilde-]";;
redirect) comp="$_comps[-redirect-]";;
math) comp="$_comps[-math-]";;
subscript) comp="$_comps[-subscript-]";;
value) comp="$_comps[-value-]";;
array_value) comp="$_comps[-array-value-]";;
condition) comp="$_comps[-condition-]";;
parameter) comp="$_comps[-parameter-]";;
brace_parameter) comp="$_comps[-brace-parameter-]";;
esac
# If not, we use default completion, if any.
[[ -z "$comp" ]] && comp="$_comps[-default-]"
[[ -z "$comp" ]] || "$comp"
fi
(( compstate[nmatches] ))

19
Completion/Core/_correct Normal file
View File

@ -0,0 +1,19 @@
#autoload
# This is mainly a wrapper around the more general `_approximate.
# By setting `compstate[pattern_match]' to something unequal to `*' and
# then calling `_approximate, we get only corrections, not all strings
# with the corrected prefix and something after it.
#
# Supported configuration keys are the same as for `_approximate', only
# starting with `correct'.
local ret=1 opm="$compstate[pattern_match]"
compstate[pattern_match]='-'
_approximate && ret=0
compstate[pattern_match]="$opm"
return ret

149
Completion/Core/_expand Normal file
View File

@ -0,0 +1,149 @@
#autoload
# This completer function is intended to be used as the first completer
# function and allows one to say more explicitly when and how the word
# from the line should be expanded than expand-or-complete.
# This function will allow other completer functions to be called if
# the expansions done produce no result or do not change the original
# word from the line.
#
# Configuration keys:
#
# expand_substitute
# If this is unset or set to the empty string, the code will first
# try to expand all substitutions in the string (such as $(...) and
# ${...}). If this is set to an non-empty string it should be
# an expression usable inside a $[...] arithmetical expression.
# In this case, expansion of substitutions will be done if the
# expression evaluates to `1'. For example, with
#
# compconf expand_substitute='NUMERIC != 1'
#
# substitution will be performed only if given an explicit numeric
# argument other than `1', as by typing ESC 2 TAB.
#
# expand_glob
# If this is unset or set to an empty string, globbing will be
# attempted on the word resulting from substitution or the
# original string. The values accepted for this key are the same
# as for expand_substitute.
#
# expand_menu
# If this is unset or set to the empty string, the words resulting
# from expansion (if any) will simply be inserted in the ommand line,
# replacing the original string. However, if this key is set to an
# non-empty string, the user can cycle through the expansion as in
# a menucompletion. Unless the value contains the sub-string `only',
# the user will still be offered all expansions at once as one of
# the strings to insert in the command line. Also, if the value
# contains the sub-string `last', the string with all expansion will
# be offered first, whereas normally it is offered as the last string
# to insert. Finally, if the value contains the sub-string `sort',
# the expansions will be sorted alphabetically, normally they are
# kept in the order the expansion produced them in.
#
# expand_original
# If this is set to an non-empty string, the original string from the
# line will be included in the list of strings the user can cycle
# through as in a menucompletion. If the value contains the sub-string
# `last', the original string will appear as the last string, with
# other values it is inserted as the first one (so that the command
# line does not change immediatly).
#
# expand_prompt
# This may be set to a string that should be displayed before the
# possible expansions. This is given to the -X option and thus may
# contain the control sequences `%n', `%B', etc. Also, the sequence
# `%o' in this string will be replaced by the original string.
local exp word="$PREFIX$SUFFIX" group=-V
# Do this only for the first global matcher.
[[ "$compstate[matcher]" -le 1 ]] || return 1
# In exp we will collect the expansion.
exp=("$word")
# First try substitution. That weird thing spanning multiple lines
# changes quoted spaces, tabs, and newlines into spaces.
[[ -z "$compconfig[expand_substitute]" ||
"${(e):-\$[$compconfig[expand_substitute]]}" -eq 1 ]] &&
exp=( "${(e)exp//\\[
]/ }" )
# If the array is empty, store the original string again.
[[ -z "$exp" ]] && exp=("$word")
# Now try globbing.
[[ -z "$compconfig[expand_glob]" ||
"${(e):-\$[$compconfig[expand_glob]]}" -eq 1 ]] &&
exp=( ${~exp}(N) )
# If we don't have any expansions or only one and that is the same
# as the original string, we let other completers run.
[[ $#exp -eq 0 ||
( $#exp -eq 1 && "$exp[1]" = "$word" ) ]] && return 1
# We have expansions, should we menucomplete them?
if [[ -z "$compconfig[expand_menu]" ]]; then
# No, so if the user only wants a list, we add the strings
# separately. Otherwise we add the whole array as one string,
# probably also adding the original string.
if [[ -z "$compstate[insert]" ]]; then
compadd -U -V _expand -Q - "$exp[@]"
else
[[ -n "$compconfig[expand_original]" &&
"$compconfig[expand_original]" != *last* ]] &&
compadd -UnQ -V _expand_original - "$word"
compadd -UQ -V _expand - "$exp"
[[ -n "$compconfig[expand_original]" &&
"$compconfig[expand_original]" = *last* ]] &&
compadd -UnQ -V _expand_original - "$word"
compstate[insert]=menu
fi
else
# Sorting? We just use a different group type then.
[[ "$compconfig[expand_menu]" = *sort* ]] && group=-J
# Now add the expansion string, probably also adding the original
# and/or the string containing all expanded string.
[[ -n "$compconfig[expand_original]" &&
"$compconfig[expand_original]" != *last* ]] &&
compadd -UnQ -V _expand_original - "$word"
[[ "$compconfig[expand_menu]" = *last* &&
"$compconfig[expand_menu]" != *only* ]] &&
compadd -UnQ -V _expand_all - "$exp"
if [[ -z "$compconfig[expand_prompt]" ]]; then
compadd -UQ $group _expand - "$exp[@]"
else
compadd -UQ -X "${compconfig[expand_prompt]//\%o/$word}" \
$group _expand - "$exp[@]"
fi
[[ "$compconfig[expand_menu]" != *last* &&
"$compconfig[expand_menu]" != *only* ]] &&
compadd -UnQ -V _expand_all - "$exp"
[[ -n "$compconfig[expand_original]" &&
"$compconfig[expand_original]" = *last* ]] &&
compadd -UnQ -V _expand_original - "$word"
compstate[insert]=menu
fi
return 0

26
Completion/Core/_files Normal file
View File

@ -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

61
Completion/Core/_list Normal file
View File

@ -0,0 +1,61 @@
#autoload
# This completer function makes the other completer functions used
# insert possible completions only after once the list has been
# shown.
#
# Configuration keys:
#
# list_condition
# If this key is unset or set to the empty string, this completer
# will delay the insertion of matches unconditionally. However,
# if this value is set, it should be set to an expression usable
# inside a $[...] arithmetical expression. In this case, delaying
# will be done if the expression evaluates to `1'.
# For example, with
#
# compconf list_condition='NUMERIC != 1'
#
# delaying will be done only if given an explicit numeric argument
# other than `1'.
#
# list_word
# To find out if only listing should be done, the code normally
# compares the contents of the line with the contents the line
# had at the time of the last invocation. If this key is set to
# an non-empty string comparison is done using only the current
# word. So if it is set, attempting completion on a word equal
# to the one completion was called on the last time will not
# delay the generation of matches.
local pre suf
# Get the strings to compare.
if [[ -z "$compconfig[list_word]" ]]; then
pre="$HISTNO$LBUFFER"
suf="$RBUFFER"
else
pre="$PREFIX"
suf="$SUFFIX"
fi
# Should we only show a list now?
if [[ ( -z "$compconfig[list_condition]" ||
"${(e):-\$[$compconfig[expand_glob]]}" -eq 1 ) &&
( "$pre" != "$_list_prefix" || "$suf" != "$_list_suffix" ) ]]; then
# Yes. Tell the completion code about it and save the new values
# to compare the next time.
compstate[insert]=''
compstate[list]=list
compstate[force_list]=yes
_list_prefix="$pre"
_list_suffix="$suf"
fi
# We always return one, because we don't really do any work here.
return 1

View File

@ -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

53
Completion/Core/_match Normal file
View File

@ -0,0 +1,53 @@
#autoload
# This is intended to be used as a completer function after the normal
# completer as in: `compconf completer=_complete:_match'.
# It temporarily switches on pattern matching, allowing you to try
# completion on patterns without having to setopt glob_complete.
#
# Note, however, that this is only really useful if you don't use the
# expand-or-complete function because otherwise the pattern will
# be expanded using globbing.
#
# Configuration key used:
#
# match_original
# If this is set to a `only', pattern matching will only be tried
# with the string from the line. If it is set to any other non-empty
# string, the original pattern will be tried first and if that yields
# no completions, matching will be tried again with a `*' inserted
# at the cursor position. If this key is not set or set to an empty
# string, matching will only be attempted with the `*' inserted.
local tmp opm="$compstate[pattern_match]" ret=0
# Do nothing if we don't have a pattern or there are still global
# match specifications to try.
tmp="${${:-$PREFIX$SUFFIX}#[~=]}"
[[ "$tmp:q" = "$tmp" ||
compstate[matcher] -ne compstate[total_matchers] ]] && return 1
# Try completion without inserting a `*'?
if [[ -n "$compconfig[match_original]" ]]; then
compstate[matcher]=-1
compstate[pattern_match]='-'
_complete && ret=1
compstate[pattern_match]="$opm"
compstate[matcher]="$compstate[total_matchers]"
(( ret )) && return 0
fi
# No completion with inserting `*'?
[[ "$compconfig[match_original]" = only ]] && return 1
compstate[matcher]=-1
compstate[pattern_match]='*'
_complete && ret=1
compstate[pattern_match]="$opm"
compstate[matcher]="$compstate[total_matchers]"
return 1-ret

View File

@ -0,0 +1,201 @@
#autoload
# This gets two arguments, a separator (which should be only one
# character) and an array. As usual, the array may be given by it's
# name or literal as in `(foo bar baz)' (words separated by spaces in
# parentheses).
# The parts of words from the array that are separated by the
# separator character are then completed independently.
local sep matches patstr orig matchflags pref i tmp1 tmp2 nm
local group expl
_match_test _multi_parts || return 1
# Save the current number of matches to be able to return if we added
# matches or not.
nm=$compstate[nmatches]
# 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 arguments, first the separator, then the array. The array is
# stored in `matches'. Further on this array will always contain those
# words from the original array that still match everything we have
# tried to match while we walk through the string from the line.
sep="$1"
if [[ "${2[1]}" = '(' ]]; then
matches=( ${2[2,-2]} )
else
matches=( "${(@P)2}" )
fi
# Now build the pattern from what we have on the line. We also save
# the original string in `orig'. The `eval' is used to replace our
# separator character by `*<sep>'.
if [[ -o globcomplete ]]; then
patstr="${PREFIX}*${SUFFIX}*"
else
patstr="${PREFIX:q}*${SUFFIX:q}*"
fi
orig="${PREFIX}${SUFFIX}"
matchflags=""
_match_pattern _path_files patstr matchflags
[[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)"
patstr="${${patstr//$sep/*$sep}//\*##/*}"
#eval patstr\="\$patstr:gs-${sep}-\*${sep}-:gs/\*\*/\*/"
# First we will skip over those parts of the matches for which we have
# exact substrings on the line. In `pref' we will build the
# unambiguous prefix string.
pref=''
while [[ "$orig" = *${sep}* ]] do
# First build the pattern to use, then collect all strings from
# `matches' that match the prefix we have and the exact substring in
# the array `tmp1'.
pat="${${${patstr#*${sep}}%${sep}*}//\*/[^${sep}]#}${patstr##*${sep}}"
tmp1=( "${(@M)matches:#${~matchflags}${orig%%${sep}*}${sep}${~pat}}" )
# If there are no words matching the exact substring, stop.
(( $#tmp1 )) || break
# Otherwise add the part to the prefix, remove it from the matches
# (which will also remove all words not matching the string at all),
# and set `patstr' and `orig' to the next component.
pref="$pref${orig%%${sep}*}${sep}"
matches=( "${(@)${(@)matches#${orig%%${sep}*}${sep}}:#}" )
orig="${orig#*${sep}}"
patstr="${patstr#*${sep}}"
done
# Now we get all the words that still match in `tmp1'.
if [[ "$patstr" = *${sep}* ]]; then
tmp1="${patstr%${sep}*}${sep}"
pat="${tmp1//\*/[^${sep}]#}${patstr##*${sep}}"
else
pat="$patstr"
fi
tmp1=( "${(@M)matches:#${~matchflags}${~pat}}" )
if (( $#tmp1 )); then
# There are words that are matched, put them int `matches' and then
# move all unambiguous components from the beginning into `pref'.
matches=( "$tmp1[@]" )
while [[ "$matches[1]" = *${sep}* ]]; do
# We just take the first component of the first match and see if
# there are other matches with a different prefix (these are
# collected in `tmp2'). If there are any, we give up.
tmp1="${matches[1]%%${sep}*}${sep}"
tmp2=( "${(@)matches:#${tmp1}*}" )
(( $#tmp2 )) && break
# All matches have the same prefix, but it into `pref' and remove
# it from the matches.
pref="$pref$tmp1"
matches=( "${(@)${(@)matches#$tmp1}:#}" )
if [[ "$orig" = *${sep}* ]]; then
orig="${orig#*${sep}}"
else
orig=''
fi
done
# Now we can tell the completion code about the things we
# found. Strings that have a separator will be added with a suffix.
if [[ -z "$orig" && "$PREFIX$SUFFIX" != "$pref$orig" ]]; then
compadd -QU "$group[@]" "$expl[@]" -i "$IPREFIX" -S '' - "${pref}${orig}"
elif [[ $compstate[insert] = *menu ]]; then
for i in "$matches[@]" ; do
if [[ "$i" = *${sep}* ]]; then
compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" \
-p "$pref" -qS "$sep" - "${i%%${sep}*}"
else
compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" \
-p "$pref" - "${i%%${sep}*}"
fi
done
else
for i in "$matches[@]" ; do
if [[ "$i" = *${sep}* ]]; then
compadd -U -i "$IPREFIX" -p "$pref" -s "${sep}${i#*${sep}}" \
"$group[@]" "$expl[@]" -M "r:|${sep}=*" - "${i%%${sep}*}"
else
compadd -U "$group[@]" "$expl[@]" -i "$IPREFIX" -p "$pref" - "$i"
fi
done
fi
elif [[ "$patstr" = *${sep}* ]]; then
# We had no words matching the string from the line. But we want to
# be friendly and at least expand the prefix as far as we can. So we
# will loop through the rest of the string from the line and test
# the components one by one.
while [[ "$patstr" = *${sep}* ]]; do
# First we get all words matching at least this component in
# `tmp1'. If there are none, we give up.
tmp1=( "${(@M)matches:#${~matchflags}${~patstr%%${sep}*}${sep}*}" )
(( $#tmp1 )) || break
# Then we check if there are words that have a different prefix.
tmp2=( "${(@)tmp1:#${tmp1[1]%%${sep}*}${sep}*}" )
if (( $#tmp2 )); then
# There are words with another prefix, so we have found an
# ambiguous component. So we just give all possible prefixes to
# the completion code together with our prefix and the rest of
# the string from the line as the suffix.
compadd -U "$group[@]" "$expl[@]" -S '' -i "$IPREFIX" -p "$pref" \
-s "${sep}${orig#*${sep}}" - "${(@)matches%%${sep}*}"
return 0
fi
# All words have the same prefix, so add it to `pref' again and
# try the next component.
pref="$pref${tmp1[1]%%${sep}*}${sep}"
matches=( "${(@)matches#${tmp1[1]%%${sep}*}${sep}}" )
orig="${orig#*${sep}}"
patstr="${patstr#*${sep}}"
done
# Finally, add the unambiguous prefix and the rest of the string
# from the line.
compadd -U "$group[@]" "$expl[@]" -S '' -i "$IPREFIX" -p "$pref" - "$orig"
fi
# This sets the return value to indicate that we added matches (or not).
[[ nm -ne compstate[nmatches] ]]

54
Completion/Core/_normal Normal file
View File

@ -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" "$@"

5
Completion/Core/_options Normal file
View File

@ -0,0 +1,5 @@
#autoload
# This should be used to complete all option names.
compgen "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o

View File

@ -0,0 +1,8 @@
#autoload
# This should be used to complete parameter names if you need some of the
# extra options of compadd. It first tries to complete only non-local
# parameters. All arguments are given to compadd.
compadd "$@" - "${(@)${(@)${(@)${(@f)$(typeset)}:#*local *\=*}%%\=*}##* }" ||
compadd "$@" - "${(@)${(@)${(@f)$(typeset)}%%\=*}##* }"

311
Completion/Core/_path_files Normal file
View File

@ -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

171
Completion/Core/_sep_parts Normal file
View File

@ -0,0 +1,171 @@
#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.:
#
# _sep_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 nm=$compstate[nmatches]
# Test if we should use this function for the global matcher in use.
_match_test _sep_parts || return 1
# 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"
[[ $#compstate[pattern_match] -ne 0 ]] || str="$str:q"
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}*}"
[[ -n "$_comp_correct" && $#test -le _comp_correct ]] && return 1
matchflags=""
_match_pattern _sep_parts test matchflags
[[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)"
test="${matchflags}${test}"
testarr=( "${(@M)${(@P)arr}:#${~test}*}" )
testarr=( "${(@)testarr:#}" )
# If there are no matches we give up. If there is more than one
# match, this is the part we will complete.
(( $#testarr )) || return 1
[[ $#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.
test="$str"
[[ -n "$_comp_correct" && $#test -le _comp_correct ]] && return 1
matchflags=""
_match_pattern _sep_parts test matchflags
[[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)"
test="${matchflags}${test}"
testarr=( "${(@M)${(@P)arr}:#${~test}*}" )
testarr=( "${(@)testarr:#}" )
fi
[[ $#testarr -eq 0 || ${#testarr[1]} -eq 0 ]] && return 1
# 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
[[ -n "$_comp_correct" && $#test -le _comp_correct ]] && return 1
matchflags=""
_match_pattern _sep_parts test matchflags
[[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)"
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
tmparr=( "${(@M)${(@P)arr}:#${~test}*}" )
tmparr=( "${(@)tmparr:#}" )
suffixes=("${(@)^suffixes[@]}${1}${(@)^tmparr}")
# 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:q}=*")
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 -U "$group[@]" "$expl[@]" "$matchers[@]" "$autosuffix[@]" \
-i "$IPREFIX" -p "$prefix" -s "$i" - "$testarr[@]"
done
# This sets the return value to indicate that we added matches (or not).
[[ nm -ne compstate[nmatches] ]]

View File

@ -0,0 +1,7 @@
#autoload
# Complete all set options. This relies on `_main_complete' to store the
# names of the options that were set when it was called in the array
# `_set_options'.
compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_set_options

View File

@ -0,0 +1,7 @@
#autoload
# Complete all unset options. This relies on `_main_complete' to store the
# names of the options that were set when it was called in the array
# `_set_options'.
compadd "$@" -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' - $=_unset_options

89
Completion/Core/compdump Normal file
View File

@ -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

269
Completion/Core/compinit Normal file
View File

@ -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

107
Completion/README Normal file
View File

@ -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.

View File

@ -0,0 +1,6 @@
DISTFILES_SRC='
.distfiles
_a2ps _compress _configure _dd _dvi _find _gunzip _gzip _hosts
_make _man _mh _pdf _ps _rcs _rlogin _strip _stty _tar _tar_archive
_tex _uncompress _x_options _xfig
'

22
Completion/User/_a2ps Normal file
View File

@ -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

View File

@ -0,0 +1,3 @@
#defcomp compress
_files -g '*~*.Z'

View File

@ -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

13
Completion/User/_dd Normal file
View File

@ -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

3
Completion/User/_dvi Normal file
View File

@ -0,0 +1,3 @@
#defcomp xdvi dvips dvibook dviconcat dvicopy dvidvi dviselect dvitodvi dvitype
_files -g '*.(dvi|DVI)'

21
Completion/User/_find Normal file
View File

@ -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

3
Completion/User/_gunzip Normal file
View File

@ -0,0 +1,3 @@
#defcomp gunzip zcat
_files -g '*.[gG][z]'

3
Completion/User/_gzip Normal file
View File

@ -0,0 +1,3 @@
#defcomp gzip
_files -g '*~*.[gG][zZ]'

3
Completion/User/_hosts Normal file
View File

@ -0,0 +1,3 @@
#defcomp ftp ncftp ping rwho rup xping traceroute nslookup
complist -k hosts

3
Completion/User/_make Normal file
View File

@ -0,0 +1,3 @@
#defcomp make gmake pmake
complist -s "\$(awk '/^[a-zA-Z0-9][^/ ]+:/ {print \$1}' FS=: [mM]akefile)"

11
Completion/User/_man Normal file
View File

@ -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

70
Completion/User/_mh Normal file
View File

@ -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

3
Completion/User/_pdf Normal file
View File

@ -0,0 +1,3 @@
function acroread
_files -g '*.(pdf|PDF)'

3
Completion/User/_ps Normal file
View File

@ -0,0 +1,3 @@
#defcomp gs ghostview gview psnup psselect pswrap pstops pstruct lpr
_files -g '*([pP][sS]|eps)'

9
Completion/User/_rcs Normal file
View File

@ -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

9
Completion/User/_rlogin Normal file
View File

@ -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

2
Completion/User/_strip Normal file
View File

@ -0,0 +1,2 @@
#defcomp strip
_files -g '*(*)'

16
Completion/User/_stty Normal file
View File

@ -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

11
Completion/User/_tar Normal file
View File

@ -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

View File

@ -0,0 +1,20 @@
#autoload
# This is used to generate filenames usable as a tar archive. This may
# get one argument, a collection of tar option characters that may be
# used to find out what kind of filename is needed. If no argument is
# given but the parameter `_tar_cmd' is set, that is used.
# If your version of `tar' supports this you may want to complete
# things like `host:file' or `user@host:file' here.
[[ $# -eq 0 && $+_tar_cmd -ne 0 ]] && set "$_tar_cmd"
if [[ "$1" = *[tx]* ]]; then
if [[ "$1" = *[zZ]* ]]; then
_files -g '*.((tar|TAR).(gz|GZ|Z)|.tgz)'
else
_files -g '*.(tar|TAR)'
fi
else
_files
fi

3
Completion/User/_tex Normal file
View File

@ -0,0 +1,3 @@
#defcomp tex latex slitex
_files -g '*.(tex|TEX|texinfo|texi)'

View File

@ -0,0 +1,3 @@
#defcomp uncompress zmore
_files -g '*.Z'

View File

@ -0,0 +1,5 @@
#defpatcomp */X11/*
# A simple pattern completion, just as an example.
complist -J options -k '(-display -name -xrm)'

3
Completion/User/_xfig Normal file
View File

@ -0,0 +1,3 @@
#defcomp xfig
_files -g '*.fig'

Some files were not shown because too many files have changed in this diff Show More