diff options
author | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:05:38 +0000 |
---|---|---|
committer | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:05:38 +0000 |
commit | e74702b467171dbdafb56dfe354794a212e020d9 (patch) | |
tree | c295b3e9b2e93e2de10331877442615b0f37e779 /Completion/Core/compinit | |
parent | c175751b501a3a4cb40ad4787340a597ea769be4 (diff) | |
download | zsh-e74702b467171dbdafb56dfe354794a212e020d9.tar.gz zsh-e74702b467171dbdafb56dfe354794a212e020d9.tar.xz zsh-e74702b467171dbdafb56dfe354794a212e020d9.zip |
Initial revision
Diffstat (limited to 'Completion/Core/compinit')
-rw-r--r-- | Completion/Core/compinit | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/Completion/Core/compinit b/Completion/Core/compinit new file mode 100644 index 000000000..ec5867838 --- /dev/null +++ b/Completion/Core/compinit @@ -0,0 +1,269 @@ +# Initialisation for new style completion. This mainly contains some helper +# function and aliases. Everything else is split into different files in this +# directory that will automatically be made autoloaded (see the end of this +# file). +# The names of the files that will be considered for autoloading have to +# start with a underscores (like `_setopt). +# The first line of these files will be read and has to say what should be +# done with its contents: +# +# `#defcomp <names ...>' +# if the first line looks like this, the file is +# autoloaded as a function and that function will +# be called to generate the matches when completing +# for one of the commands whose <name> is given +# +# `#defpatcomp <pattern>' +# this defines a function that should be called to generate +# matches for commands whose name matches <pattern>; note +# that only one pattern may be given +# +# `#defkeycomp <style> [ <key-sequence> ... ] +# this is used to bind special completions to all the given +# <key-sequence>(s). The <style> is the name of one of the built-in +# completion widgets (complete-word, delete-char-or-list, +# expand-or-complete, expand-or-complete-prefix, list-choices, +# menu-complete, menu-expand-or-complete, or reverse-menu-complete). +# This creates a widget behaving like <style> so that the +# completions are chosen as given in the the rest of the file, +# rather than by the context. The widget has the same name as +# the autoload file and can be bound using bindkey in the normal way. +# +# `#autoload' +# this is for helper functions that are not used to +# generate matches, but should automatically be loaded +# when they are called +# +# Note that no white space is allowed between the `#' and the rest of +# the string. +# +# See the file `compdump' for how to speed up initialiation. +# +# If you are using global matching specifications with `compctl -M ...' +# have a look at the files `_match_test' and `_match_pattern'. To make +# all the example functions use matching as specified with `-M' these +# need some editing. +# +# If we got the `-d'-flag, we will automatically dump the new state (at +# the end). + +if [[ "$1" = -d ]]; then + _i_autodump=1 +else + _i_autodump=0 +fi + +# The associative array containing the definitions for the commands. +# Definitions for patterns will be stored in the normal array `_patcomps'. + +typeset -A _comps +_patcomps=() + +# This function is used to register or delete completion functions. For +# registering completion functions, it is invoked with the name of the +# function as it's first argument (after the options). The other +# arguments depend on what type of completion function is defined. If +# none of the `-p' and `-k' options is given a function for a command is +# defined. The arguments after the function name are then interpreted as +# the names of the command for which the function generates matches. +# With the `-p' option a function for a name pattern is defined. This +# function will be invoked when completing for a command whose name +# matches the pattern given as argument after the function name (in this +# case only one argument is accepted). +# With the `-k' option a function for a special completion keys is +# defined and immediatly bound to those keys. Here, the extra arguments +# are the name of one of the builtin completion widgets and any number +# of key specifications as accepted by the `bindkey' builtin. +# In any case the `-a' option may be given which makes the function +# whose name is given as the first argument be autoloaded. When defining +# a function for command names the `-n' option may be given and keeps +# the definitions from overriding any previous definitions for the +# commands. +# For deleting definitions, the `-d' option must be given. Without the +# `-p' option, this deletes definitions for functions for the commands +# whose names are given as arguments. If combined with the `-p' option +# it deletes the definitions for the patterns given as argument. +# The `-d' option may not be combined with the `-k' option, i.e. +# definitions for key function can not be removed. +# +# Examples: +# +# compdef -a foo bar baz +# make the completion for the commands `bar' and `baz' use the +# function `foo' and make this function be autoloaded +# +# compdef -p foo 'c*' +# make completion for all command whose name begins with a `c' +# generate matches by calling the function `foo' before generating +# matches defined for the command itself +# +# compdef -k foo list-choices '^X^M' '\C-xm' +# make the function `foo' be invoked when typing `Control-X Control-M' +# or `Control-X m'; the function should generate matches and will +# behave like the `list-choices' builtin widget +# +# compdef -d bar baz +# delete the definitions for the command names `bar' and `baz' + +compdef() { + local opt autol type func delete new i + + # Get the options. + + while getopts "anpkd" opt; do + case "$opt" in + a) autol=yes;; + n) new=yes;; + [pk]) if [[ -n "$type" ]]; then + # Error if both `-p' and `-k' are given (or one of them + # twice). + echo "$0: type already set to $type" + return 1 + fi + if [[ "$opt" = p ]]; then + type=pattern + else + type=key + fi + ;; + d) delete=yes;; + esac + done + shift OPTIND-1 + + if [[ -z "$delete" ]]; then + # Adding definitions, first get the name of the function name + # and probably do autoloading. + + func="$1" + [[ -n "$autol" ]] && autoload "$func" + shift + + case "$type" in + pattern) + if [[ $# -gt 1 ]]; then + echo "$0: only one pattern allowed" + return 1 + fi + # Patterns are stored in strings like `c* foo', with a space + # between the pattern and the function name. + + _patcomps=("$_patcomps[@]" "$1 $func") + ;; + key) + if [[ $# -lt 2 ]]; then + echo "$0: missing keys" + return 1 + fi + + # Define the widget. + zle -C "$func" "$1" "$func" + shift + + # And bind the keys... + for i; do + bindkey "$i" "$func" + done + ;; + *) + # For commands store the function name in the `_comps' + # associative array, command names as keys. + for i; do + [[ -z "$new" || "${+_comps[$i]}" -eq 0 ]] && _comps[$i]="$func" + done + ;; + esac + else + # Handle the `-d' option, deleting. + case "$type" in + pattern) + # Note the space. + for i; do + _patcomps=("${(@)patcomps:#$i *}") + done + ;; + key) + # Oops, cannot do that yet. + + echo "$0: cannot restore key bindings" + return 1 + ;; + *) + # Deleting definitons for command is even simpler. + for i; do + unset "_comps[$i]" + done + esac + fi +} + +# Now we automatically make the definition files autoloaded. + +# First we get the name of a dump file if this will be used. + +: ${COMPDUMP:=$0.dump} + +if [[ ! -o extendedglob ]]; then + _i_noextglob=yes + setopt extendedglob +fi + +typeset -U _i_files +_i_files=( ${^~fpath}/_*~*~(N:t) ) +_i_initname=$0 +_i_done='' + +# If we have a dump file, load it. + +if [[ -f "$COMPDUMP" ]]; then + read -rA _i_line < "$COMPDUMP" + if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files ]]; then + builtin . "$COMPDUMP" + _i_done=yes + fi + unset _i_line +fi +if [[ -z "$_i_done" ]]; then + for _i_dir in $fpath; do + [[ $_i_dir = . ]] && continue + for _i_file in $_i_dir/_*~*~(N); do + read -rA _i_line < $_i_file + _i_tag=$_i_line[1] + shift _i_line + if [[ $_i_tag = '#defcomp' ]]; then + compdef -na "${_i_file:t}" "${_i_line[@]}" + elif [[ $_i_tag = '#defpatcomp' ]]; then + compdef -pa "${_i_file:t}" "${_i_line[@]}" + elif [[ $_i_tag = '#defkeycomp' ]]; then + compdef -ka "${_i_file:t}" "${_i_line[@]}" + elif [[ $_i_tag = '#autoload' ]]; then + autoload ${_i_file:t} + fi + done + done + + bindkey | + while read -rA _i_line; do + if [[ "$_i_line[2]" = complete-word || + "$_i_line[2]" = delete-char-or-list || + "$_i_line[2]" = expand-or-complete || + "$_i_line[2]" = expand-or-complete-prefix || + "$_i_line[2]" = list-choices || + "$_i_line[2]" = menu-complete || + "$_i_line[2]" = menu-expand-or-complete || + "$_i_line[2]" = reverse-menu-complete ]]; then + zle -C _complete_$_i_line[2] $_i_line[2] _main_complete + bindkey "${_i_line[1][2,-2]}" _complete_$_i_line[2] + fi + done + + unset _i_dir _i_line _i_file _i_tag + + # If autodumping was requested, do it now. + + (( _i_autodump )) && builtin . ${_i_initname:h}/compdump +fi + +[[ -z "$_i_noextglob" ]] || unsetopt extendedglob + +unset _i_files _i_initname _i_done _i_autodump _i_noextglob |