Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
completion grouping
- X-seq: zsh-workers 8520
- From: Sven Wischnowsky <wischnow@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxx
- Subject: completion grouping
- Date: Wed, 3 Nov 1999 14:41:35 +0100 (MET)
- Mailing-list: contact zsh-workers-help@xxxxxxxxxxxxxx; run by ezmlm
It may be far too early to post this, but I thought that maybe someone
would like to help...
We had this discussion about allowing users to specify when they want
to see which matches. The patch below (which, maybe, not everyone
should apply right away, although it doesn't actually break
completion) is my first attempt/suggestion for this. There are still
many open issues, so I'll be asking many questions again. But first a
short description of the present state:
Completion functions should call the function `_tags' with the
tag-names of the types of matches they generate. Then they call
`_tags' repeatedly without arguments. This will set the parameter
`tags' to a colon-separated list of tags then should now be
tried. E.g. if a functions generates jobs (`%...') and pids, it should
do something like:
local prios tags
_tags job process
while _tags; do
if [[ "$tags" = *:job:* ]]; then
# generate jobs
fi
if [[ "$tags" = *:process:* ]]; then
# generate pids
fi
[[ matches generated ]] && break
done
`prios' is used internally by `_tags' to remember the tag-sets to
report on consecutive calls. `tags' always begins and ends with a
colon to make the tests simpler.
The need to declare `prios' and `tags' as locals is very ugly, but
currently I don't see a really satisfying solution. We could accept
any name and make `_tags' get those names as arguments, but that isn't
much better.
Ok. `_tags' uses the assoc `comptags' which maps tag names to colon-
separated lists of entries of the form: `pat=prio' or `pat=prio[style]'
as suggested by Peter. I.e. the `pat' is a pattern which is compared
to the command name or, if it begins with `_', the name of the calling
function (this is slightly different from Peter's suggestion, but I
think specifying these on a per-command basis is more natural).
`_tags' looks at the entries for the tags it gets, compares all
patterns and uses the entry for the first matching pattern. The
entries found for all tags are sorted by the `prio'rity in ascending
order. Entries with a negative priority are ignored, i.e. a user can
say `process=-1' to never be offered pids as possible matches (when
all functions completing them use this tag).
The optional `style' is my answer to the `describe_options' ugliness.
I wanted to be able to remove them, integrating them with this
grouping stuff. So the patch below changes `_arguments' (and
`_describe' and `_values') to make them test these styles. It goes
like this: a user sets `comptags[option]="1=*[describe]"'. When
`_tags' is called from `_arguments' and friends the `tags' parameter
gets set to `option[describe]'. So they can test which `style' of
option completion is wanted and turn on/off descriptions (in this
example). Currently this is only used for `describe' (description
yes/no), `prefix' (complete options only if the `-/+/--' prefix is on
the line), and `hide' (hide the `-/+/--' prefix in the list).
Ok, as I said, I have changed only very few functions until now.
Namely: `_arguments' which uses the `argument' and `option' tags,
`_values' which uses only the `value' tag (but that can be combined
with the `[describe]' style), `_files' which uses `glob', `path', and
`file' (not `anyfile', as suggested by Peter), and finally `_kill' and
`_wait' (as examples for normal completion functions) which both use
the `job' and `process' tags.
The patch also sets up the `comptags' assoc in `compinit' and puts the
overall default value in it. This is stored as the tag `any', i.e. if
`_tags' doesn't find an entry for a tag in `comptags', it uses the
entry for `any'.
To allow easier testing/playing, this also adds the function `comptag'
to `compinit'. The syntax is comparable to `compconfig', with some
small additions. Examples:
comptag argument='*=1'
make `_arguments' give a high priority to normal arguments
comptag option='*=2[describe]'
together with the previous one, this means that options are only
completed by `_arguments' if no normal arguments could be
completed; also, describe options
comptag option+='*dvi*=1'
the `+=' means that the definition is prepended to the already
existing definition for the `option' tag; this means that for
`*dvi*' commands options are immediately completed together with
normal arguments but they won't be described
comptag option-='*dvi*'
this removes the previous definition
Other definitions one might want to try out (the ones for the `_files'
function):
comptag glob='*=1' path='*=2' file='*=3'
this makes it first try only the glob pattern (if any), then
directories are tried, and then any file
comptag glob='*=1' path='*=1' file='*=3'
this is like `-/g', i.e. it will immediately try the glob patterns
*plus* directories; if that fails, all files are completed
comptag glob='*=1' file='*=3'
only glob patterns or all files
comptag glob='*=1' path='*=1' file='*dvi*=-1:*=3'
... for `*dvi*' commands, never complete all files
Of course, you can also list the tags set in the same way as with
`compconf'. All this isn't perfect yet (as you can easily see), I only
wanted to make life a bit easier.
So, now the questions/remarks (in no particular order):
- Peter suggested a utility function `_priorities' (or something like
that). This would be quite easy to implement but I haven't done that
yet. I'm not sure how often this would be useful to have...
- Other utility functions need to be changed too.
- The online-help Peter suggested: I thought a lot about ways to
implement this. For now I could only think of something like this:
Let all completion function call a utility function `_help' at the
beginning which gets the documentation string as an argument. This
will be stored somewhere and the function continues as usual. Then
we either make `_tags' report the `help' tag and the functions have
to handle that (calling another function to add the help texts), or
we allow the arguments to `_tags' contain (optional?) descriptions,
so that these help texts can be generated half-automatically. Or
maybe we allow both. The real problem is with functions like
`_arguments'. Here we sometimes need to get the `argument' tag so
that the match-generating functions are called and they can add
their own help texts. This could probably be done by telling `_tags'
about these special tags, e.g. if an arguments starts with `-', this
means that the tag should be reported even if we are only collecting
help texts.
Another problem might be functions like `_kill' which complete
different things depending on a prefix (or some other condition).
Currently `_kill' uses `_tags' only if not completing after a `-'.
I'm not too happy with any of this, so suggestions are particularly
welcome here.
- I want bindable commands (or functions like `predict-on') to
influence which tags are use. The patch already contains some code
for this (but no example functions): `compinit' defines the
`override_tags' assoc. The keys are used as tags and the values may
be:
- a priority (i.e. a number)
- a `prio[style]' string
- only a `[style]' (this keeps the normal priority and overrides
only the style
- anything from the above preceded by a `+'; if at least one of
the tags added by the first call to `_tags' has such a value,
only these tags are used, all others will not be reported
In `_main_complete' lists of offered/used/unused/... tags are stored
in `_lastcomp' (look at `${(kv)_lastcomp[(I)*tags]}" if you're
interested).
- We might want to add more default values (in `compinit') and to find
a better way for defining global defaults (not using the `any' tag).
But this should definitely wait until this has become stable.
- Docs will have to be written. I didn't do that yet because this is
so experimental that it didn't seem worth it.
Ok. Comments?
Bye
Sven
diff -u -r oldcompletion/Base/_arguments Completion/Base/_arguments
--- oldcompletion/Base/_arguments Wed Nov 3 14:10:36 1999
+++ Completion/Base/_arguments Wed Nov 3 13:26:38 1999
@@ -154,122 +154,127 @@
if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
local nm="$compstate[nmatches]" action noargs aret expl local
local next direct odirect equal single match matched ws tmp1 tmp2
+ local prios tags opts
- if ! comparguments -D descr action; then
+ if comparguments -D descr action; then
+ if comparguments -O next direct odirect equal; then
+ opts=yes
+ _tags -f "$funcstack[2]" argument option
+ else
+ _tags -f "$funcstack[2]" argument
+ fi
+ else
if comparguments -a; then
noargs='no more arguments'
else
noargs='no arguments'
fi
- fi
-
- while true; do
+ comparguments -O next direct odirect equal || return 1
- if [[ -z "$noargs" || -n "$matched" ]]; then
- _description expl "$descr"
+ opts=yes
+ _tags -f "$funcstack[2]" option
+ fi
- if [[ "$action" = -\>* ]]; then
- comparguments -W line opt_args
- state="${${action[3,-1]##[ ]#}%%[ ]#}"
- compstate[restore]=''
- aret=yes
- else
- if [[ -z "$local" ]]; then
- local line
- typeset -A opt_args
- local=yes
- fi
+ while _tags; do
+ while true; do
+ if [[ "$tags" = *:argument* ]]; then
+ _description expl "$descr"
+
+ if [[ "$action" = -\>* ]]; then
+ comparguments -W line opt_args
+ state="${${action[3,-1]##[ ]#}%%[ ]#}"
+ compstate[restore]=''
+ aret=yes
+ else
+ if [[ -z "$local" ]]; then
+ local line
+ typeset -A opt_args
+ local=yes
+ fi
- comparguments -W line opt_args
+ comparguments -W line opt_args
- if [[ "$action" = \ # ]]; then
+ if [[ "$action" = \ # ]]; then
- # An empty action means that we should just display a message.
+ # An empty action means that we should just display a message.
- [[ -n "$matched" ]] && compadd -n -Q -S '' -s "$SUFFIX" - "$PREFIX"
- mesg="$descr"
+ [[ -n "$matched" ]] && compadd -n -Q -S '' -s "$SUFFIX" - "$PREFIX"
+ mesg="$descr"
- elif [[ "$action" = \(\(*\)\) ]]; then
+ elif [[ "$action" = \(\(*\)\) ]]; then
- # ((...)) contains literal strings with descriptions.
+ # ((...)) contains literal strings with descriptions.
- eval ws\=\( "${action[3,-3]}" \)
+ eval ws\=\( "${action[3,-3]}" \)
- _describe -c "$cmd" "$descr" ws -M "$match"
+ _describe -c "$cmd" -f "$funcstack[2]" "$descr" ws -M "$match"
- elif [[ "$action" = \(*\) ]]; then
+ elif [[ "$action" = \(*\) ]]; then
- # Anything inside `(...)' is added directly.
+ # Anything inside `(...)' is added directly.
- compadd "$expl[@]" - ${=action[2,-2]}
- elif [[ "$action" = \{*\} ]]; then
+ compadd "$expl[@]" - ${=action[2,-2]}
+ elif [[ "$action" = \{*\} ]]; then
- # A string in braces is evaluated.
+ # A string in braces is evaluated.
- eval "$action[2,-2]"
+ eval "$action[2,-2]"
- elif [[ "$action" = \ * ]]; then
+ elif [[ "$action" = \ * ]]; then
- # If the action starts with a space, we just call it.
+ # If the action starts with a space, we just call it.
- ${(e)=~action}
- else
+ ${(e)=~action}
+ else
- # Otherwise we call it with the description-arguments built above.
+ # Otherwise we call it with the description-arguments built above.
- action=( $=action )
- ${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]}
+ action=( $=action )
+ ${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]}
+ fi
fi
fi
- fi
-
- if [[ -z "$matched" ]] &&
- comparguments -O next direct odirect equal &&
- [[ ( ( nm -eq compstate[nmatches] || -n "$noargs" ) &&
- -z "$aret" && -z "$mesg" ) ||
- -z "$compconfig[option_prefix]" ||
- "$compconfig[option_prefix]" = *\!${cmd}* ||
- "$PREFIX" = [-+]* ]]; then
-
- comparguments -M match
-
- if comparguments -s single; then
-
- _description expl option
-
- if [[ "$single" = direct ]]; then
- compadd "$expl[@]" -QS '' - "${PREFIX}${SUFFIX}"
- elif [[ "$single" = next ]]; then
- compadd "$expl[@]" -Q - "${PREFIX}${SUFFIX}"
- elif [[ "$single" = equal ]]; then
- compadd "$expl[@]" -QqS= - "${PREFIX}${SUFFIX}"
+ if [[ "$tags" = *:option* &&
+ ( "$tags" != *\[*prefix*\]* || "$PREFIX" = [-+]* ) ]]; then
+ comparguments -M match
+
+ if comparguments -s single; then
+
+ _description expl option
+
+ if [[ "$single" = direct ]]; then
+ compadd "$expl[@]" -QS '' - "${PREFIX}${SUFFIX}"
+ elif [[ "$single" = next ]]; then
+ compadd "$expl[@]" -Q - "${PREFIX}${SUFFIX}"
+ elif [[ "$single" = equal ]]; then
+ compadd "$expl[@]" -QqS= - "${PREFIX}${SUFFIX}"
+ else
+ tmp1=( "$next[@]" "$direct[@]" "$odirect[@]" "$equal[@]" )
+ tmp1=( "${(M@)tmp1:#[-+]?(|:*)}" )
+ tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
+
+ _describe -o -c "$cmd" -f "$funcstack[2]" option \
+ tmp1 tmp2 -Q -S ''
+ fi
+ single=yes
else
- tmp1=( "$next[@]" "$direct[@]" "$odirect[@]" "$equal[@]" )
- tmp1=( "${(M@)tmp1:#[-+]?(|:*)}" )
- tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
-
- _describe -o -c "$cmd" option tmp1 tmp2 -Q -S ''
+ next=( "$next[@]" "$odirect[@]" )
+ _describe -o -c "$cmd" -f "$funcstack[2]" option \
+ next -Q -M "$match" -- \
+ direct -QS '' -M "$match" -- \
+ equal -QqS= -M "$match"
fi
- single=yes
- else
- next=( "$next[@]" "$odirect[@]" )
- _describe -o -c "$cmd" option \
- next -Q -M "$match" -- \
- direct -QS '' -M "$match" -- \
- equal -QqS= -M "$match"
fi
-
- if [[ nm -eq compstate[nmatches] && -z "$aret" &&
- ( ( -z "$single" && "$PREFIX" = [-+]*\=* ) ||
- "$PREFIX" = --* ) ]]; then
+ if [[ -n "$opts" && -z "$aret$matched" && nm -ne compstate[nmatches] &&
+ "$tags" = *:argument* ]]; then
local prefix suffix
- prefix="${PREFIX#*\=}"
- suffix="$SUFFIX"
- PREFIX="${PREFIX%%\=*}"
- SUFFIX=''
- compadd -M "$match" -D equal - "${(@)equal%%:*}"
+ prefix="${PREFIX#*\=}"
+ suffix="$SUFFIX"
+ PREFIX="${PREFIX%%\=*}"
+ SUFFIX=''
+ compadd -M "$match" -D equal - "${(@)equal%%:*}"
if [[ $#equal -eq 1 ]]; then
PREFIX="$prefix"
@@ -277,11 +282,13 @@
IPREFIX="${IPREFIX}${equal[1]%%:*}="
matched=yes
comparguments -L "$equal[1]" descr action
+ tags=argument
continue
- fi
+ fi
fi
- fi
- break
+ break
+ done
+ [[ -n "$aret" || nm -ne compstate[nmatches] ]] && break
done
[[ -n "$aret" ]] && return 300
@@ -292,7 +299,6 @@
# Set the return value.
[[ nm -ne "$compstate[nmatches]" ]]
-
else
return 1
fi
diff -u -r oldcompletion/Base/_describe Completion/Base/_describe
--- oldcompletion/Base/_describe Wed Nov 3 14:10:36 1999
+++ Completion/Base/_describe Wed Nov 3 13:26:38 1999
@@ -2,15 +2,19 @@
# This can be used to add options or values with descriptions as matches.
-local isopt cmd opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide
+local cmd func opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide
+local prios tags type=value
cmd="$words[1]"
+func="$funcstack[2]"
# Get the options.
-while getopts 'oc:' opt; do
+while getopts 'oc:f:' opt; do
if [[ "$opt" = o ]]; then
- isopt=yes
+ type=option
+ elif [[ "$opt" = f ]]; then
+ func="$OPTARG"
else
cmd="$OPTARG"
fi
@@ -19,28 +23,11 @@
# Do the tests. `showd' is set if the descriptions should be shown.
-if [[ -n "$isopt" ]]; then
+_tags -c "$cmd" -f "$func" "$type"
- # We take the value to test the number of matches from a non-local
- # parameter `nm' if that exists and contains only digits. It's a hack.
+_tags || return 1
- if [[ "$nm" = [0-9]## ]]; then
- _nm="$nm"
- else
- _nm=0
- fi
- [[ -n "$compconfig[option_prefix]" &&
- "$compconfig[option_prefix]" != *\!${cmd}* &&
- "$PREFIX" != [-+]* &&
- ( "$compconfig[option_prefix]" = *nodefault* ||
- _nm -ne compstate[nmatches] ) ]] && return 1
-
- [[ -n "$compconfig[describe_options]" &&
- "$compconfig[describe_options]" != *\!${cmd}* ]] && showd=yes
-else
- [[ -n "$compconfig[describe_values]" &&
- "$compconfig[describe_values]" != *\!${cmd}* ]] && showd=yes
-fi
+[[ "$tags" = *:${type}\[*describe*\]* ]] && showd=yes
_description expl "$1"
shift
@@ -51,7 +38,7 @@
compdescribe -i "$@"
fi
-[[ -n "$isopt" && "$compconfig[option_prefix]" = hide* ]] && hide=yes
+[[ "$type" = option && "$tags" = *:option\[*hide*\]* ]] && hide=yes
while compdescribe -g args tmpd tmpmd tmps tmpms; do
diff -u -r oldcompletion/Base/_values Completion/Base/_values
--- oldcompletion/Base/_values Wed Nov 3 14:10:36 1999
+++ Completion/Base/_values Wed Nov 3 13:26:38 1999
@@ -2,9 +2,13 @@
if compvalues -i "$@"; then
- local noargs args opts descr action expl sep
+ local tags prios noargs args opts descr action expl sep
if ! compvalues -D descr action; then
+
+ _tags value
+ _tags || return 1
+
compvalues -V noargs args opts
if [[ "$PREFIX" = *\=* ]]; then
@@ -39,7 +43,7 @@
sep=()
fi
- _describe "$descr" \
+ _describe -f "$funcstack[2]" "$descr" \
noargs "$sep[@]" -M 'r:|[_-]=* r:|=*' -- \
args -S= -M 'r:|[_-]=* r:|=*' -- \
opts -qS= -M 'r:|[_-]=* r:|=*'
@@ -48,6 +52,9 @@
fi
fi
+ _tags argument
+ _tags || return 1
+
_description expl "$descr"
# We add the separator character as a autoremovable suffix unless
@@ -80,7 +87,7 @@
eval ws\=\( "${action[3,-3]}" \)
- _describe "$descr" ws -M 'r:|[_-]=* r:|=*'
+ _describe -f "$funcstack[2]" "$descr" ws -M 'r:|[_-]=* r:|=*'
elif [[ "$action" = \(*\) ]]; then
diff -u -r oldcompletion/Builtins/_kill Completion/Builtins/_kill
--- oldcompletion/Builtins/_kill Wed Nov 3 14:10:36 1999
+++ Completion/Builtins/_kill Wed Nov 3 13:27:53 1999
@@ -6,14 +6,21 @@
_description expl signal
compadd "$expl[@]" $signals[1,-3]
else
- local ret=1
-
- _jobs && ret=0
-
- list=("${(@M)${(f@)$(ps ${=compconfig[ps_listargs]:-$=compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*}")
- _description expl 'process ID'
- compadd "$expl[@]" -ld list - ${${${(f)"$(ps $=compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} &&
- ret=0
+ local prios tags ret=1
+
+ _tags job process
+
+ while _tags; do
+ [[ "$tags" = *:job:* ]] && _jobs && ret=0
+ if [[ "$tags" = *:process:* ]]; then
+ list=("${(@M)${(f@)$(ps ${=compconfig[ps_listargs]:-$=compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*}")
+ _description expl 'process ID'
+ compadd "$expl[@]" -ld list - \
+ ${${${(f)"$(ps $=compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} &&
+ ret=0
+ fi
+ (( ret )) || break
+ done
return ret
fi
diff -u -r oldcompletion/Builtins/_wait Completion/Builtins/_wait
--- oldcompletion/Builtins/_wait Wed Nov 3 14:10:36 1999
+++ Completion/Builtins/_wait Wed Nov 3 13:28:29 1999
@@ -1,11 +1,19 @@
#compdef wait
-local list ret=1 expl
-
-_jobs && ret=0
-
-list=("${(@M)${(f)$(ps ${=compconfig[ps_listargs]:-$=compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*}")
-_description expl 'process ID'
-compadd "$expl[@]" -ld list - ${${${(f)"$(ps $=compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} && ret=0
+local prios tags list ret=1 expl
+
+_tags job process
+
+while _tags; do
+ [[ "$tags" = *:job:* ]] && _jobs && ret=0
+ if [[ "$tags" = *:process:* ]]; then
+ list=("${(@M)${(f@)$(ps ${=compconfig[ps_listargs]:-$=compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*}")
+ _description expl 'process ID'
+ compadd "$expl[@]" -ld list - \
+ ${${${(f)"$(ps $=compconfig[ps_args] 2>/dev/null)"}[2,-1]## #}%% *} &&
+ ret=0
+ fi
+ (( ret )) || break
+done
return ret
diff -u -r oldcompletion/Core/_files Completion/Core/_files
--- oldcompletion/Core/_files Wed Nov 3 14:10:37 1999
+++ Completion/Core/_files Wed Nov 3 13:26:39 1999
@@ -1,31 +1,27 @@
#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 opts opt type=file prios tags
-local nm=$compstate[nmatches] ret=1
+opts=()
+while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:" opt; do
+ case "$opt" in
+ /) [[ "$type" = file ]] && type=dir ;;
+ g) [[ "$type" = (file|dir) ]] && type="$OPTARG" ;;
+ q) opts=("$opts[@]" -q ) ;;
+ [^f]) opts=("$opts[@]" "-$opt" "$OPTARG") ;;
+ esac
+done
+
+case "$type" in
+file) _tags -f "$funcstack[2]" file ;;
+dir) _tags -f "$funcstack[2]" path file ;;
+*) _tags -f "$funcstack[2]" glob path file ;;
+esac
+
+while _tags; do
+ [[ "$tags" = *:file:* ]] && { _path_files "$opts[@]" -f ; return }
+ [[ "$tags" = *:path:* ]] && _path_files "$opts[@]" -/ && return 0
+ [[ "$tags" = *:glob:* ]] && _path_files "$opts[@]" -g "$type" && return 0
+done
-_path_files "$@" && ret=0
-
-if [[ $# -ne 0 && compstate[nmatches] -eq 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 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:qr:R:W:F:J:V:X:f/g:M:" opt; do
- case "$opt" in
- f) return;;
- [PSrRWFJVXM]) opts=("$opts[@]" "-$opt" "$OPTARG");;
- q) opts=("$opts[@]" -q);;
- esac
- done
-
- _path_files "$opts[@]" && ret=0
-fi
-
-return ret
+return 1
diff -u -r oldcompletion/Core/_main_complete Completion/Core/_main_complete
--- oldcompletion/Core/_main_complete Wed Nov 3 14:10:37 1999
+++ Completion/Core/_main_complete Wed Nov 3 13:26:39 1999
@@ -17,7 +17,12 @@
# state than the global one for which you are completing.
-local comp post ret=1 _compskip
+local comp post ret=1 _compskip prios tags
+typeset -U _offered_tags _tried_tags _failed_tags _used_tags _unused_tags
+
+_offered_tags=()
+_tried_tags=()
+_failed_tags=()
typeset -U _lastdescr
@@ -46,6 +51,11 @@
fi
done
+# See which tags were or were not used.
+
+_used_tags=( "${(@)_tried_tags:#${(j:|:)~${(@)_failed_tags//\[/\\[}//\]/\\]}}" )
+_unused_tags=( "${(@)_offered_tags:#${(j:|:)~${(@)_used_tags//\[/\\[}//\]/\\]}}" )
+
# Now call the post-functions.
for post in "$comppostfuncs[@]"; do
@@ -82,5 +92,10 @@
_lastcomp[isuffix]="$ISUFFIX"
_lastcomp[qiprefix]="$QIPREFIX"
_lastcomp[qisuffix]="$QISUFFIX"
+_lastcomp[offered_tags]="${(j.:.)_offered_tags}"
+_lastcomp[tried_tags]="${(j.:.)_tried_tags}"
+_lastcomp[failed_tags]="${(j.:.)_failed_tags}"
+_lastcomp[unused_tags]="${(j.:.)_unused_tags}"
+_lastcomp[used_tags]="${(j.:.)_used_tags}"
return ret
diff -u -r oldcompletion/Core/_tags Completion/Core/_tags
--- oldcompletion/Core/_tags Wed Nov 3 14:10:37 1999
+++ Completion/Core/_tags Wed Nov 3 14:08:42 1999
@@ -0,0 +1,81 @@
+#autoload
+
+if (( $# )); then
+ local cmd="$words[1]" func="$funcstack[2]" defs i tags tag pat style prio
+
+ while getopts 'c:f:' i; do
+ if [[ "$i" = c ]]; then
+ cmd="$OPTARG"
+ else
+ func="$OPTARG"
+ fi
+ done
+
+ shift OPTIND-1
+
+ defs=( "${(@M)argv:#${(kj:|:)~override_tags[(R)(|+*)]}}" )
+ (( $#defs )) && set -- "$defs[@]"
+
+ _offered_tags=( "$_offered_tags[@]" "$@" )
+ _last_tags=()
+
+ defs=()
+ for i; do
+ if [[ -n ${override_tags[$i]} && ${override_tags[$i]} != (\[|+\[)* ]]; then
+ if [[ ${override_tags[$i]} = *\[* ]]; then
+ prio=( "${i}:*=${override_tags[$i]#+}" )
+ else
+ prio=( "${i}:${(@v)^comptags[(I)(|*:)${i}(|:*)]}" )
+ (( $#prio )) || prio=( "${i}:${comptags[any]}" )
+ prio="${${${prio[(r)(|*:)\*=[^:]#\[*\](|:*)]}##(|*:)\*}%%:*}"
+ prio=( "${i}:*=${override_tags[$i]#+}${(M)prio%%\[*\]}" )
+ fi
+ else
+ prio=( "${i}:${(@v)^comptags[(I)(|*:)${i}(|:*)]}" )
+ (( $#prio )) || prio=( "${i}:${comptags[any]}" )
+ fi
+ defs=( "$defs[@]" "$prio[@]" )
+ done
+
+ tags=()
+ for i in "$defs[@]"; do
+ tag="${i%%:*}"
+ for pat in "${(s.:.)i#*:}"; do
+ if [[ ( "$pat" = _* && "$func" = ${~pat%%\=*} ) ||
+ "$cmd" = ${~pat%%\=*} ]]; then
+ prio="${pat#*\=}"
+ [[ "$prio" = -* ]] && continue 2
+
+ if [[ "$prio" = *\[*\] ]]; then
+ style="${(M)prio%%\[*}"
+ prio="${prio%%\[*}"
+ else
+ style=''
+ fi
+ [[ ${override_tags[$tag]} = (|+)\[* ]] &&
+ style="${override_tags[$tag]#+}"
+
+ (( prio++ ))
+
+ tags[$prio]="${tags[$prio]}:${tag}${style}"
+ break
+ fi
+ done
+ done
+
+ prios=( "${(@)tags:#}" )
+
+ return 0
+fi
+
+_failed_tags=( "$_failed_tags[@]" "$_last_tags[@]" )
+
+(( $#prios )) || return 1
+
+tags="${prios[1]}:"
+shift 1 prios
+
+_last_tags=( "${(@s.:.)${${tags#:}%:}}" )
+_tried_tags=( "$_tried_tags[@]" "$_last_tags[@]" )
+
+return 0
diff -u -r oldcompletion/Core/compinit Completion/Core/compinit
--- oldcompletion/Core/compinit Wed Nov 3 13:25:59 1999
+++ Completion/Core/compinit Wed Nov 3 13:26:40 1999
@@ -108,6 +108,14 @@
compconfig[correct_prompt]='correct to:'
(( ${+compconfig[completer]} )) || compconfig[completer]=_complete
+# This holds the tag/priority definitions.
+
+typeset -gA comptags
+
+(( ${+comptags[any]} )) || comptags[any]='*=100'
+
+typeset -gA override_tags
+
# This can hold names of functions that are to be called after all
# matches have been generated.
@@ -365,6 +373,74 @@
print "compconf $i='$compconfig[$i]'"
else
print ${(r:25:)i} "$compconfig[$i]"
+ fi
+ done
+ fi
+}
+
+# Function to set tags and priorities.
+
+comptag() {
+ local i opt list tag val
+
+ while getopts "lL" opt; do
+ if [[ "$opt" = l ]]; then
+ [[ -z "$list" ]] && list=yes
+ else
+ list=long
+ fi
+ done
+ shift OPTIND-1
+
+ if (( $# )); then
+ if [[ -n $list ]]; then
+ for i; do
+ if [[ $list = long ]]; then
+ (( ${+comptags[$i]} )) && print "comptag $i='$comptags[$i]'"
+ else
+ print $comptags[$i]
+ fi
+ done
+ else
+ for i; do
+ tag="${i%%([-+]|)\=*}"
+ val="${${i#*(|[-+])\=}#+}"
+ case "$i" in
+ *+\=*)
+ if [[ -n "$comptags[$tag]" ]]; then
+ comptags[$tag]="${val}:${comptags[$tag]}"
+ else
+ comptags[$tag]="$val"
+ fi
+ ;;
+ *\=+*)
+ if [[ -n "$comptags[$tag]" ]]; then
+ comptags[$tag]="${comptags[$tag]}:${val}"
+ else
+ comptags[$tag]="$val"
+ fi
+ ;;
+ *-\=*)
+ if [[ -n "$comptags[$tag]" ]]; then
+ comptags[$tag]="${${${comptags[$tag]//:${val}\=[^:]##}#${val}\=*:}%:${val}\=[^:]##}"
+ [[ "$comptags[$tag]" = ${val}\=* ]] && unset "comptags[$tag]"
+ fi
+ ;;
+ *\=*)
+ comptags[${i%%\=*}]="${i#*\=}"
+ ;;
+ *)
+ unset "compconfig[$i]"
+ ;;
+ esac
+ done
+ fi
+ else
+ for i in ${(ok)comptags}; do
+ if [[ $list = long ]]; then
+ print "comptag $i='$comptags[$i]'"
+ else
+ print ${(r:25:)i} "$comptags[$i]"
fi
done
fi
--
Sven Wischnowsky wischnow@xxxxxxxxxxxxxxxxxxxxxxx
Messages sorted by:
Reverse Date,
Date,
Thread,
Author