1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-11 00:51:05 +02:00
zsh/Functions/Completion/init
1999-04-15 18:16:27 +00:00

221 lines
6.9 KiB
Text

# 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 `dump' for how to speed up initialiation.
# 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
# This may be used to define completion handlers. The first argument is the
# name of the function containing the definition, the other arguments are the
# command names for which this definition should be used.
# With only one argument the function/variable-name _$1 is used.
# If given the `-a' option, the function is defined as being autoloaded.
defcomp() {
local name
if [[ "$1" = -a ]]; then
shift
autol=yes
fi
if [[ $# -eq 1 ]]; then
comps[$1]="_$1"
[[ -z "$autol" ]] || autoload "_$1"
else
name="$1"
shift
for i; do
comps[$i]="$name"
done
[[ -z "$autol" ]] || autoload "$name"
fi
}
# Almost like `defcomp', but this always gets two arguments: the name of a
# function describing what should be completed and the pattern that will be
# compared to the command names for which completion is attempted.
defpatcomp() {
if [[ "$1" = -a ]]; then
shift
autoload "$1"
fi
if (( $+patcomps )) then
patcomps=("$patcomps[@]" "$2 $1")
else
patcomps=("$2 $1")
fi
}
# This is used to define completion handlers directly bound to keys. The
# first argument is as for `defcomp', giving the handler. The second
# argument is the name of one of the built-in completion widgets. Any
# remaining arguments are used as key sequences to bind the widget.
# Typing that key sequence will complete the word the cursor is on
# according to the completion definition given and will behave as if the
# built-in completion widget was used.
defkeycomp() {
local name
if [[ "$1" = -a ]]; then
shift
autoload "$1"
fi
name="$1"
shift
zle -C "$name" "$1" "$name"
shift
while (( $# )); do
bindkey "$1" "$name"
shift
done
}
# This searches $1 in the array for normal completions and calls the result.
_compalso() {
local tmp
tmp="$comps[$1]"
[[ -z "$tmp" ]] || "$tmp" "$@"
}
# These can be used to easily save and restore the state of the special
# variables used by the completion code.
alias _compsave='local _oprefix$_level _oiprefix$_level _oargv$_level _ocurrent$_level _ocommand$_level _ocontext$_level; \
eval "_oprefix${_level}=\"\$PREFIX\"; \
_oiprefix${_level}=\"\$IPREFIX\"; \
_oargv${_level}=( \"\$@\" ); \
_ocurrent${_level}=\"\$CURRENT\"; \
_ocommand${_level}=\"\$COMMAND\"; \
_ocontext${_level}=\"\$CONTEXT\""'
alias _compreset='eval "PREFIX=\"\$_oprefix${_level}\"; \
IPREFIX=\"\$_oiprefix${_level}\"; \
argv=( \"\$_oargv${_level}[@]\" ); \
CURRENT=\"\$_ocur${_level}\"; \
COMMAND=\"\$_ocommand${_level}\"; \
CONTEXT=\"\$_ocontext${_level}\""'
# These can be used to build tests that modify the special parameters
# without having to reset them by hand.
alias _if='(( $+_level )) || local _level=0; (( _level++ )); _compsave; if'
alias _elif='_compreset; elif'
alias _else='_compreset; else'
alias _fi='_compreset; fi; unset _oprefix$_level _oiprefix$_level _oargv$_level _ocurrent$_level _ocommand$_level _ocontext$_level; (( _level-- ))'
# 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}
_i_files=( ${^~fpath}/_*~*~ )
_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
defcomp -a ${_i_file:t} "${_i_line[@]}"
elif [[ $_i_tag = '#defpatcomp' ]]; then
defpatcomp -a "${_i_file:t}" "${_i_line[@]}"
elif [[ $_i_tag = '#defkeycomp' ]]; then
defkeycomp -a "${_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}/dump
fi
unset _i_files _i_initname _i_done _i_autodump