From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 554 invoked from network); 25 Feb 1999 16:34:41 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 25 Feb 1999 16:34:41 -0000 Received: (qmail 15314 invoked by alias); 25 Feb 1999 16:34:26 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 5529 Received: (qmail 15306 invoked from network); 25 Feb 1999 16:34:25 -0000 Date: Thu, 25 Feb 1999 17:33:42 +0100 (MET) Message-Id: <199902251633.RAA30088@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk Subject: Completion example cleanup The patch below... - merges the `def*comp' functions into one `compdef', this is almost the only function you have to worry about when starting to play with the examples - renames `comps' and `patcomps' to `_comps' and `_patcomps' - removes some calls to `compsub' that have survived the removal of that function (oops!) - removes the `compsave'/`comprest' aliases and the `_if*' stuff; all of these weren't used anyway and with the upcoming (more explicit) completion testing syntax they wouldn't be used anyway - makes `_compalso' autoloaded - removes the need for the `_kill_helper' function (small item, but it was on my todo list); Peter: if this patch makes it in, you can remove `_kill_helper' in pws-10 (`patch' can't do that, can it?) Ok, this solves almost none of the problems Andrej mentioned, but makes the code somewhat cleaner, I think. Bye Sven diff -u of/Completion/_builtin Functions/Completion/_builtin --- of/Completion/_builtin Thu Feb 25 11:18:26 1999 +++ Functions/Completion/_builtin Thu Feb 25 16:12:22 1999 @@ -1,7 +1,7 @@ #defcomp builtin if [[ -position 2 -1 ]]; then - compsub + _normal "$@" else complist -eB fi diff -u Functions/Completion/_compalso Functions/Completion/_compalso --- Functions/Completion/_compalso Thu Feb 25 17:25:21 1999 +++ Functions/Completion/_compalso Thu Feb 25 16:32:52 1999 @@ -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" "$@" diff -u of/Completion/_kill Functions/Completion/_kill --- of/Completion/_kill Thu Feb 25 11:18:28 1999 +++ Functions/Completion/_kill Thu Feb 25 16:07:35 1999 @@ -1,8 +1,11 @@ #defcomp kill +local list + if [[ -iprefix '-' ]]; then complist -k "($signals[1,-3])" else complist -P '%' -j - complist -y _kill_helper -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' + list=("$(ps 2>/dev/null)") + complist -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' fi diff -u of/Completion/_main_complete Functions/Completion/_main_complete --- of/Completion/_main_complete Thu Feb 25 11:18:28 1999 +++ Functions/Completion/_main_complete Thu Feb 25 16:18:59 1999 @@ -14,7 +14,7 @@ # Completion functions may set `COMPSKIP' to any value to make the # main loops stop calling other completion functions. -comp="$comps[-first-]" +comp="$_comps[-first-]" if [[ ! -z "$comp" ]]; then "$comp" "$@" if (( $+COMPSKIP )); then @@ -34,15 +34,15 @@ comp='' case $CONTEXT in - redirect) comp="$comps[-redirect-]";; - math) comp="$comps[-math-]";; - subscript) comp="$comps[-subscript-]";; - value) comp="$comps[-value-]";; - condition) comp="$comps[-condition-]";; + 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="$_comps[-default-]" [[ -z "$comp" ]] || "$comp" "$@" fi diff -u of/Completion/_normal Functions/Completion/_normal --- of/Completion/_normal Thu Feb 25 11:18:28 1999 +++ Functions/Completion/_normal Thu Feb 25 16:21:28 1999 @@ -7,7 +7,7 @@ # a path and the last path name component). if [[ $CONTEXT == command ]]; then - comp="$comps[-command-]" + comp="$_comps[-command-]" [[ -z "$comp" ]] || "$comp" "$@" return elif [[ "$COMMAND[1]" == '=' ]]; then @@ -23,8 +23,8 @@ # See if there are any matching pattern completions. -if (( $#patcomps )); then - for i in "$patcomps[@]"; do +if (( $#_patcomps )); then + for i in "$_patcomps[@]"; do pat="${i% *}" val="${i#* }" if [[ "$cmd1" == $~pat || "$cmd2" == $~pat ]]; then @@ -40,17 +40,17 @@ # Now look up the two names in the normal completion array. name="$cmd1" -comp="$comps[$cmd1]" +comp="$_comps[$cmd1]" if [[ -z "$comp" ]]; then name="$cmd2" - comp="$comps[$cmd2]" + comp="$_comps[$cmd2]" fi # And generate the matches, probably using default completion. if [[ -z "$comp" ]]; then name=-default- - comp="$comps[-default-]" + comp="$_comps[-default-]" fi [[ -z "$comp" ]] || "$comp" "$@" diff -u of/Completion/_sched Functions/Completion/_sched --- of/Completion/_sched Thu Feb 25 11:18:29 1999 +++ Functions/Completion/_sched Thu Feb 25 16:12:36 1999 @@ -1,3 +1,3 @@ #defcomp sched -[[ -position 2 -1 ]] && compsub +[[ -position 2 -1 ]] && _normal "$@" diff -u of/Completion/_source Functions/Completion/_source --- of/Completion/_source Thu Feb 25 11:18:29 1999 +++ Functions/Completion/_source Thu Feb 25 16:12:59 1999 @@ -1,7 +1,7 @@ #defcomp source if [[ -position 2 -1 ]]; then - compsub + _normal "$@" else _files fi diff -u of/Completion/_wait Functions/Completion/_wait --- of/Completion/_wait Thu Feb 25 11:18:30 1999 +++ Functions/Completion/_wait Thu Feb 25 16:08:55 1999 @@ -1,4 +1,7 @@ #defcomp wait +local list + complist -P '%' -j -complist -y _kill_helper -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' +list=("$(ps 2>/dev/null)") +complist -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' diff -u of/Completion/dump Functions/Completion/dump --- of/Completion/dump Thu Feb 25 11:18:30 1999 +++ Functions/Completion/dump Thu Feb 25 16:21:42 1999 @@ -22,18 +22,18 @@ unset _d_files -# First dump the arrays comps and patcomps. The quoting hieroglyphyics +# 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]//\'/'\\''}'" +print "_comps=(" >> $_d_file +for _d_f in ${(ok)_comps}; do + print -r - "'${_d_f//\'/'\\''}'" "'${_comps[$_d_f]//\'/'\\''}'" done >> $_d_file print ")" >> $_d_file -if (( $#patcomps )); then - print "\npatcomps=(" >> $_d_file - for _d_f in "$patcomps[@]"; do +if (( $#_patcomps )); then + print "\n_patcomps=(" >> $_d_file + for _d_f in "$_patcomps[@]"; do print -r - "'${_d_f//\'/'\\''}'" done >> $_d_file print ")" >> $_d_file diff -u of/Completion/init Functions/Completion/init --- of/Completion/init Thu Feb 25 11:18:30 1999 +++ Functions/Completion/init Thu Feb 25 17:27:02 1999 @@ -38,7 +38,12 @@ # the string. # # See the file `dump' 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). @@ -49,120 +54,152 @@ fi # The associative array containing the definitions for the commands. -# Definitions for patterns will be stored in the normal array `patcomps'. +# Definitions for patterns will be stored in the normal array `_patcomps'. -typeset -A comps +typeset -A _comps +# 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' -# 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 `-n' option, the function name is stored only if there wasn't -# an older definition for the command. -# If given the `-a' option, the function is defined as being autoloaded. +compdef() { + local opt autol type func delete new i -defcomp() { - local opt name autol new + # Get the options. - while getopts "na" opt; do + while getopts "anpkd" opt; do case "$opt" in - a) autol=yes;; - n) new=yes;; + 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 [[ $# -eq 1 ]]; then - if [[ -z "$new" || "${+comps[$1]}" -eq 0 ]]; then - comps[$1]="_$1" - [[ -z "$autol" ]] || autoload "_$1" - fi - else - name="$1" - shift - for i; do - [[ -z "$new" || "${+comps[$i]}" -eq 0 ]] && 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. + if [[ -z "$delete" ]]; then + # Adding definitions, first get the name of the function name + # and probably do autoloading. -defpatcomp() { - if [[ "$1" = -a ]]; then + func="$1" + [[ -n "$autol" ]] && autoload "$func" 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" + 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. + + if (( $+_patcomps )); then + _patcomps=("$_patcomps[@]" "$1 $func") + else + _patcomps=("$1 $func") + fi + ;; + 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" "$name" + 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 - 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. @@ -196,11 +233,11 @@ _i_tag=$_i_line[1] shift _i_line if [[ $_i_tag = '#defcomp' ]]; then - defcomp -n -a ${_i_file:t} "${_i_line[@]}" + compdef -na "${_i_file:t}" "${_i_line[@]}" elif [[ $_i_tag = '#defpatcomp' ]]; then - defpatcomp -a "${_i_file:t}" "${_i_line[@]}" + compdef -pa "${_i_file:t}" "${_i_line[@]}" elif [[ $_i_tag = '#defkeycomp' ]]; then - defkeycomp -a "${_i_file:t}" "${_i_line[@]}" + compdef -ka "${_i_file:t}" "${_i_line[@]}" elif [[ $_i_tag = '#autoload' ]]; then autoload ${_i_file:t} fi -- Sven Wischnowsky wischnow@informatik.hu-berlin.de