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:
parent
c175751b50
commit
e74702b467
|
@ -0,0 +1,3 @@
|
|||
DISTFILES_SRC='
|
||||
.distfiles README
|
||||
'
|
|
@ -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
|
||||
'
|
|
@ -0,0 +1,5 @@
|
|||
#defcomp -brace-parameter-
|
||||
|
||||
# Simple but without spiffy suffix handling: compgen -v -S '} '
|
||||
|
||||
compadd -S '} ' -r '-:?#%+=[/' - "${(@)${${${(f)$(typeset)}%%\=*}##* }:gs/'//}"
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp -command-
|
||||
|
||||
complist -c
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp -equal-
|
||||
|
||||
compgen -am
|
|
@ -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
|
|
@ -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.
|
|
@ -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 ))
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp -parameter-
|
||||
|
||||
compgen -v
|
|
@ -0,0 +1,5 @@
|
|||
#defcomp - nohup nice eval time rusage noglob nocorrect exec
|
||||
|
||||
[[ -position 1 -1 ]]
|
||||
|
||||
_normal "$@"
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp -redirect-
|
||||
|
||||
_files
|
|
@ -0,0 +1,4 @@
|
|||
#defcomp -subscript-
|
||||
|
||||
_compalso -math- "$@"
|
||||
[[ ${(Pt)${COMMAND}} = assoc* ]] && complist -k "( ${(kP)${COMMAND}} )"
|
|
@ -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/
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp -math- getopts read unset vared
|
||||
|
||||
complist -v
|
|
@ -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
|
||||
'
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp unalias
|
||||
|
||||
complist -a
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp shift
|
||||
|
||||
complist -A
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp autoload
|
||||
|
||||
complist -s '${^fpath}/*(N:t)'
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp bg
|
||||
|
||||
complist -z -P '%'
|
|
@ -0,0 +1,7 @@
|
|||
#defcomp bindkey
|
||||
|
||||
if [[ -mword 1 -*[DAN]* || -mcurrent -1 -*M ]]; then
|
||||
complist -s '$(bindkey -l)'
|
||||
else
|
||||
complist -b
|
||||
fi
|
|
@ -0,0 +1,7 @@
|
|||
#defcomp builtin
|
||||
|
||||
if [[ -position 2 -1 ]]; then
|
||||
_normal "$@"
|
||||
else
|
||||
complist -eB
|
||||
fi
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp cd
|
||||
|
||||
_files -W cdpath -g '*(-/)'
|
|
@ -0,0 +1,7 @@
|
|||
#defcomp command
|
||||
|
||||
if [[ -position 2 -1 ]]; then
|
||||
_normal "$@"
|
||||
else
|
||||
complist -em
|
||||
fi
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp rmdir df du dircmp
|
||||
|
||||
_files -/
|
|
@ -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
|
|
@ -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)'
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
#defcomp fc
|
||||
|
||||
if [[ -mcurrent -1 -*e ]]; then
|
||||
complist -c
|
||||
elif [[ -mcurrent -1 -[ARWI]## ]]; then
|
||||
_files
|
||||
fi
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp unfunction
|
||||
|
||||
complist -F
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp fg jobs
|
||||
|
||||
complist -j -P '%'
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp limit unlimit
|
||||
|
||||
complist -k "(${(j: :)${(f)$(limit)}%% *})"
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp sched
|
||||
|
||||
[[ -position 2 -1 ]] && _normal "$@"
|
|
@ -0,0 +1,7 @@
|
|||
#defcomp set
|
||||
|
||||
if [[ -mcurrent -1 [-+]o ]]; then
|
||||
complist -o
|
||||
elif [[ -current -1 -A ]]; then
|
||||
complist -A
|
||||
fi
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
#defcomp source
|
||||
|
||||
if [[ -position 2 -1 ]]; then
|
||||
_normal "$@"
|
||||
else
|
||||
_files
|
||||
fi
|
|
@ -0,0 +1,7 @@
|
|||
#defcomp trap
|
||||
|
||||
if [[ -position 1 ]]; then
|
||||
complist -c
|
||||
else
|
||||
complist -k signals
|
||||
fi
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp declare export integer local readonly typeset
|
||||
|
||||
complist -v -q -S '='
|
|
@ -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`'
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp which whence where type
|
||||
|
||||
complist -caF
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
#defcomp zle
|
||||
|
||||
if [[ -word 1 -N && -position 3 ]]; then
|
||||
complist -F
|
||||
else
|
||||
complist -b
|
||||
fi
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
DISTFILES_SRC='
|
||||
.distfiles _correct_filename _most_recent_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
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
#defkeycomp complete-word \C-xm
|
||||
local file
|
||||
file=($~PREFIX*$~SUFFIX(om[1]N))
|
||||
(( $#file )) && compadd -f $file
|
|
@ -0,0 +1,5 @@
|
|||
DISTFILES_SRC='
|
||||
.distfiles
|
||||
_compalso _files _main_complete _multi_parts _normal _path_files
|
||||
_sep_parts compdump compinit
|
||||
'
|
|
@ -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
|
|
@ -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
|
|
@ -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" "$@"
|
|
@ -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] ))
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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] ]]
|
|
@ -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" "$@"
|
|
@ -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
|
|
@ -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)}%%\=*}##* }"
|
|
@ -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
|
|
@ -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] ]]
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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.
|
|
@ -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
|
||||
'
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp compress
|
||||
|
||||
_files -g '*~*.Z'
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp xdvi dvips dvibook dviconcat dvicopy dvidvi dviselect dvitodvi dvitype
|
||||
|
||||
_files -g '*.(dvi|DVI)'
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp gunzip zcat
|
||||
|
||||
_files -g '*.[gG][z]'
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp gzip
|
||||
|
||||
_files -g '*~*.[gG][zZ]'
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp ftp ncftp ping rwho rup xping traceroute nslookup
|
||||
|
||||
complist -k hosts
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp make gmake pmake
|
||||
|
||||
complist -s "\$(awk '/^[a-zA-Z0-9][^/ ]+:/ {print \$1}' FS=: [mM]akefile)"
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
function acroread
|
||||
|
||||
_files -g '*.(pdf|PDF)'
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp gs ghostview gview psnup psselect pswrap pstops pstruct lpr
|
||||
|
||||
_files -g '*([pP][sS]|eps)'
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
#defcomp strip
|
||||
_files -g '*(*)'
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp tex latex slitex
|
||||
|
||||
_files -g '*.(tex|TEX|texinfo|texi)'
|
|
@ -0,0 +1,3 @@
|
|||
#defcomp uncompress zmore
|
||||
|
||||
_files -g '*.Z'
|
|
@ -0,0 +1,5 @@
|
|||
#defpatcomp */X11/*
|
||||
|
||||
# A simple pattern completion, just as an example.
|
||||
|
||||
complist -J options -k '(-display -name -xrm)'
|
|
@ -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
Loading…
Reference in New Issue