summaryrefslogtreecommitdiff
path: root/Completion/Core/compinit
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Core/compinit')
-rw-r--r--Completion/Core/compinit269
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