* completion grouping
@ 1999-11-03 13:41 Sven Wischnowsky
1999-11-03 17:12 ` Bart Schaefer
0 siblings, 1 reply; 8+ messages in thread
From: Sven Wischnowsky @ 1999-11-03 13:41 UTC (permalink / raw)
To: zsh-workers
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@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: completion grouping
1999-11-03 13:41 completion grouping Sven Wischnowsky
@ 1999-11-03 17:12 ` Bart Schaefer
0 siblings, 0 replies; 8+ messages in thread
From: Bart Schaefer @ 1999-11-03 17:12 UTC (permalink / raw)
To: zsh-workers
On Nov 3, 2:41pm, Sven Wischnowsky wrote:
} Subject: completion grouping
}
} 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
Can I first suggest that we spell out "priorities"? It's not like it's
going to be typed very often, is it?
I'm also never sure what to expect from "sorted by priority." In this
case a smaller number is a higher priority, right? But a negative
number is treated as bigger than any positive one? That's a bit weird.
Or am I misunderstanding?
} The need to declare `prios' and `tags' as locals is very ugly, but
} currently I don't see a really satisfying solution.
I've been thinking about something for that, but so far it's too nebulous
to tell if it's going to work.
} comptag option+='*dvi*=1'
}
} the `+=' means that the definition is prepended to the already
} existing definition
Hrm. I would have expected += to *append* rather than *prepend* (my
C++ is showing).
Otherwise, this looks pretty good.
Perhaps more on the other questions later; I have a cramp in my neck this
morning which is making it difficult to type.
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: completion grouping
@ 1999-11-05 15:40 Sven Wischnowsky
0 siblings, 0 replies; 8+ messages in thread
From: Sven Wischnowsky @ 1999-11-05 15:40 UTC (permalink / raw)
To: zsh-workers
Oliver Kiddle wrote:
> ...
>
> I may not have properly understood your tags and priority system but I'm
> not convinced that it is worth the extra complexity in the completion
> functions to be able to configure the order that different groups are
> completed. Could the system use the groups specified with compadd -V /
> -J? Also, could the system be done so that for example, _jobs would call
> _tags to say it is generating jobs as opposed to every completion
> function which calls _jobs. Basically, what I'm saying, is can we reduce
> the extra complexity that it adds to the functions.
The quick answer is: No.
Currently, the amount of work needed to make a functionm use tags is:
- for a function/context that completes only one type of matches:
local tags
_tags -i <tag-name> || return 1
that's all. Currently this can only be used by users to say if they
want any matches at all or not, so it isn't really useful. But I'd
like to make sure we use it everywhere so that if we once add the
online-documentation stuff we already have the needed calls
everywhere.
- for functions adding multiple types of matches:
local tags
_tags <tag-names...>
while _tags; do
if [[ "$tags" = ... ]]; then ...; fi
if [[ "$tags" = ... ]]; then ...; fi
...
[[ <matches generated> ]] && break
done
(or some other tests on "$tags"). And because of this we can't move
that code into the helper functions like `_jobs': only the calling
function (e.g. `_kill') knows what different types of matches can be
generated and thus knows if there are other tags to try if one failed.
But, again: completion functions without that will work as before, so
users writing their own little functions don't really have to worry
about all this. Only if they want them to be included in an official
release it would be nice if they use/supply/support everything the
completion system offers. But in most cases it shouldn't be too hard
for one of us to add that code to functions we get (if we get any at
all).
> ...
>
> > So, like Bart I'd really like to have things stabilize. The tags- and
> > config- stuff is partly meant as a final cleanup (partly; the other
> > part is to add a missing bit I should have thought about from the
>
> I'd also agree on the stability point. If we get a 4.0 out, we might
> also get some feedback from more normal users.
I'm trying to enforce this discussion because I don't like the thought
that we hurry to get 4.0 out of the door and later decide (based on
our experience or user requests) that it would be nice to make things
better configurable. It may well be that this would require changing
the way things are configured and user would have to change their
setup in the release-after-the-next-one. I only want to make sure that
we release it in a form that allows us to enhance it without making
user setups invalid.
> ...
>
> I found the system quite hard to understand initially. There are a
> number of points I've never really understood properly, like the
> differences between the different types of prefix/suffix or whats going
> on with some of the functions which handle menu-completion. I've mostly
> found it quite easy to write a completion which basically works but I'm
> never very sure that it is totally correct.
Basically I'd say that if they do what you want, they are correct. The
only thing that I missed from some of the functions submitted were the
calls to `_description'. Currently that's the only thing one really
has to remember -- and if you use one of the helper functions like
`_arguments' this should be forced (although in some cases it would be
nice if people weren't so lazy to omit the option-descriptions -- but
I've done that myself already, so I better not complain too loudly; ahem).
> In many ways I find it
> easier than the old compctls. I always found compctls to be very hard to
> read compared to tcsh completes and tended to need the manual next to me
> for constant reference on the option names which was annoying.
>
> The main things which I would want to configure with the new completions
> is often how the completions are listed and when. For example, I don't
> like the job completion after bart-8 which completes by the job number
> rather than the name of the command:
> %<tab> will list, for e.g.:
>
> [ 1] man less
> [ 2] less config.h
>
> And will complete to %1 or %2. I think it should return to completing
> the commands after '%' or a config key should select.
I did that because I once had the case where two jobs started with the
same word (and I really hate getting `%foo\ really\ long\ argument\ list').
> I also don't like
> that kill will complete job names straight-away as opposed to only after
> an inital '%'. It seems a bit weird when a job gets listed twice - once
> as the job and once in the ps listing.
Jobs aren't only just processes, but this is *exactly* what we (at
least I, and I think Peter, too) want to achieve with this priority
mechanism. You don't like it, so you should have a way to say that you
want to see jobs only after a `%' or that you first want pids and if
there is no match, fall back on jobs. That's also why I immediately
changed the config keys for the option/argument stuff into tags --
there we had it already and I want to make it easier/generic/less-ad-hoc
to be able to specify this in more places.
Your request to get names instead of job numbers, btw, fits nicely
into the style-mechanism I want to have (it's comparable to the describe-
options stuff).
> In a few cases I've found that other people's completions have taken the
> approach of completing everything which is valid in a particular context
> whereas I prefer to keep the number of matches down to a minimum, for
> example, by only completing options after an initial '-' and jobs after
> a '%'. This is the main sort of thing which I think should be
> configurable.
See above.
> As an aside, we seem to have a few cases where we complete to a numbered
> list:
> cd ~+<tab>
> cd -<tab>
> cd $path[<tab>
> fg %<tab>
> are all examples, yet we aren't very consistent in how we display the
> numbers:
> '[ 1] ', '1 -- ', '1) ' are all used. Maybe this format should be
> configurable.
In one of my last patches I changed the job-list to use ` -- ', too. I
was first comparing it to the output of `jobs'. The `1)' is in the
subscript code, right? Yes, we should change that.
Bye
Sven
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: completion grouping
1999-11-05 10:52 completion grouping (PLEASE read this) Sven Wischnowsky
@ 1999-11-05 14:54 ` Oliver Kiddle
0 siblings, 0 replies; 8+ messages in thread
From: Oliver Kiddle @ 1999-11-05 14:54 UTC (permalink / raw)
To: Zsh workers
Sven Wischnowsky wrote:
>
> The grouping and configuration stuff I wrote about lately certainly
> sounded like an attempt to make things even more complicated. It wasn't.
> Actually -- and that's what I wanted to say when mentioning that I
> want an easier user interface for the configuration stuff -- I would
> like to make it simpler.
I suppose that what we need to identify is what sort of things the
average normal user will want to configure: offering just those things
in an easy to configure way will be helpful but making to much
configurable with simple commands will just make the functions too
complex. I would expect that the main thing normal users would want is
to be able to add completions for any commands which are specific to
their system. To help this, writing completion functions should be
atleast as easy as writing the old compctls.
Where I really like the new system is that it allows us to define how to
complete various different things like URLs, jobs, files etc in one
place and then reference these in the completion for a specific command,
using a full meaning-full name. It also means that anyone can change the
way a specific type of thing is completed for all commands that complete
that type by changing the function. The trouble is that many of the
supplied functions have become very complicated.
I may not have properly understood your tags and priority system but I'm
not convinced that it is worth the extra complexity in the completion
functions to be able to configure the order that different groups are
completed. Could the system use the groups specified with compadd -V /
-J? Also, could the system be done so that for example, _jobs would call
_tags to say it is generating jobs as opposed to every completion
function which calls _jobs. Basically, what I'm saying, is can we reduce
the extra complexity that it adds to the functions.
> Another thing that may help is adding good default values for our
> configuration parameters (this is a bit like the discussion about the
> options that we decided to set by default). When I first started
> adding config keys I sometimes asked if people think we should add a
> default for them -- due to no replies I later gave up asking that. But
I agree that we should put some thought into default values for the
config keys. For some, it probably makes no sense to have a default.
Also, with some, the comfig key being unset might have a significant
meaning at the moment so we would need to implement a way of specifying
that meaning.
> So, like Bart I'd really like to have things stabilize. The tags- and
> config- stuff is partly meant as a final cleanup (partly; the other
> part is to add a missing bit I should have thought about from the
I'd also agree on the stability point. If we get a 4.0 out, we might
also get some feedback from more normal users.
> beginning). But I need help. It would already help to hear about your
> experiences, descriptions about how you use the completion stuff. How
> you learnt about it. Do you use configuration?
I use the configuration though probably not a huge amount.
> Are there things you are
> missing? Or (more probably?) do you find it too overwhelming? How hard
> is it for you to write completion functions? How can we help?
I found the system quite hard to understand initially. There are a
number of points I've never really understood properly, like the
differences between the different types of prefix/suffix or whats going
on with some of the functions which handle menu-completion. I've mostly
found it quite easy to write a completion which basically works but I'm
never very sure that it is totally correct. In many ways I find it
easier than the old compctls. I always found compctls to be very hard to
read compared to tcsh completes and tended to need the manual next to me
for constant reference on the option names which was annoying.
The main things which I would want to configure with the new completions
is often how the completions are listed and when. For example, I don't
like the job completion after bart-8 which completes by the job number
rather than the name of the command:
%<tab> will list, for e.g.:
[ 1] man less
[ 2] less config.h
And will complete to %1 or %2. I think it should return to completing
the commands after '%' or a config key should select. I also don't like
that kill will complete job names straight-away as opposed to only after
an inital '%'. It seems a bit weird when a job gets listed twice - once
as the job and once in the ps listing.
In a few cases I've found that other people's completions have taken the
approach of completing everything which is valid in a particular context
whereas I prefer to keep the number of matches down to a minimum, for
example, by only completing options after an initial '-' and jobs after
a '%'. This is the main sort of thing which I think should be
configurable.
As an aside, we seem to have a few cases where we complete to a numbered
list:
cd ~+<tab>
cd -<tab>
cd $path[<tab>
fg %<tab>
are all examples, yet we aren't very consistent in how we display the
numbers:
'[ 1] ', '1 -- ', '1) ' are all used. Maybe this format should be
configurable.
Oliver Kiddle
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: completion grouping
1999-11-04 9:32 Sven Wischnowsky
@ 1999-11-05 7:20 ` Bart Schaefer
0 siblings, 0 replies; 8+ messages in thread
From: Bart Schaefer @ 1999-11-05 7:20 UTC (permalink / raw)
To: zsh-workers
On Nov 4, 10:32am, Sven Wischnowsky wrote:
} Subject: Re: completion grouping
}
} Bart Schaefer wrote:
}
} > I'm also never sure what to expect from "sorted by priority." In this
} > case a smaller number is a higher priority, right? But a negative
} > number is treated as bigger than any positive one? That's a bit weird.
} > Or am I misunderstanding?
}
} No. Only tags with a positive (or zero) priority are used and then
} smaller numbers mean higher priorities (hm, maybe we should change
} that if people think that that would feel more natural).
Not necessarily "more natural."
} > } comptag option+='*dvi*=1'
} > }
} > } the `+=' means that the definition is prepended to the already
} > } existing definition
} >
} > Hrm. I would have expected += to *append* rather than *prepend* (my
} > C++ is showing).
}
} Looking at my mail again I noticed that I forgot to mention that `+='
} prepends and `=+' appends. With that said this hopefully looks more
} sensible ;-)
Hmm.
} But I'd like think about changing this function anyway. I.e. I hope to
} find a somewhat easier interface. Currently this is still too near to
} the way things are stored in `$comptags' and I think the user shouldn't
} have to worry/know about the internal representation.
I don't see how you can avoid having the user know *something* about at
least the ordering of the alternatives for a given tag, so although I'm
not entirely happy with the syntax I don't mind the semantics.
} we probably should think about some standard structure for defining
} styles. Things like multiple styles (separated by commas?), styles
} with values (`[style_a=foo,style_b=bar]' or something like that). If
} this turns out to be useful, I would like change `_tags' to report
} styles in a format that is easier to parse in the calling functions.
I repeat my suggestion that this be enveloped in a mini-language, as with
the _arg_compile function.
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: completion grouping
1999-11-04 13:50 Sven Wischnowsky
@ 1999-11-04 17:46 ` Bart Schaefer
0 siblings, 0 replies; 8+ messages in thread
From: Bart Schaefer @ 1999-11-04 17:46 UTC (permalink / raw)
To: zsh-workers
On Nov 4, 2:50pm, Sven Wischnowsky wrote:
} Subject: Re: completion grouping
}
} (I'm beginning to think that maybe everyone should apply 8520 and 8533
} even though I said otherwise in 8520 -- it's probably easier to
} build/change that than to keep different versions alive.)
Has anybody else been feeling a bit like Dr. Frankenstein lately?
I think everyone should go ahead and apply 8520 and 8533. However:
} After having a look at the keys as listed in the compsys doc, I'm back
} again at the idea to combine configuration definitions and tag
} definitions -- but this time the other way round. There are only very
} few config keys for which it is really completely unnecessary to let
} user define them per-command.
To rephrase to be sure I understand: Much of what's in the compconfig AA
controls behavior that could reasonably be expected to differ depending
on the command or context for which completion is being performed.
Although I don't disagree with this assessment, perhaps it's time to take
a deep breath and look again at the usability of the whole system. How
many users are going to expend the effort to alter their compconfig even
once, let alone multiple times? I've certainly made few changes myself.
Didn't we originally set out to make it easier for mere mortals to create
their own completions, on the premise that writing a shell function was
easier than using compctl -x syntax?
Now instead we seem to be attempting to write all the completion functions
in advance, to cover every possible behavior, and provide configuration
keys (which are often every bit as complex as the old -x syntax) to select
among those behaviors. We've made a huge step forward in power and maybe
expressiveness, but I'm beginning to think we've only gone sideways on
usability. The main advantage of the new system is that it's more, well,
complete, so that an average user probably no longer needs to define any
new functions at all.
Which is not necessarily a bad thing ... but it means that putting further
effort into detailed adjustments has diminishing returns, as it's going to
be less and less likely that anyone bothers to understand it.
And wouldn't it be nice to have this all stabilize sometime soon, so PWS
can do a non-beta 3.2-or-4.0-or-whatever release? We're now just 48 days
from the three-year anniversary of zsh-3.1.0!
I'm not trying to discourage any of the stuff that Sven has suggested; but
when answering his questions, let's try to look at it from slightly farther
away, in terms of not just what it's expressing, but how likely it is that
a non-programmer is going to be able to do anything useful with it.
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: completion grouping
@ 1999-11-04 13:50 Sven Wischnowsky
1999-11-04 17:46 ` Bart Schaefer
0 siblings, 1 reply; 8+ messages in thread
From: Sven Wischnowsky @ 1999-11-04 13:50 UTC (permalink / raw)
To: zsh-workers
(I'm beginning to think that maybe everyone should apply 8520 and 8533
even though I said otherwise in 8520 -- it's probably easier to
build/change that than to keep different versions alive.)
I wrote:
> I also forgot to mention another thing that may be interesting: I
> already used the style-stuff for `describe_option' and friends. That
> was easy to think about because they allowed definitions on a per-
> command basis already. But ther may be other things we currently use
> config keys for which may be interesting to turn into styles so that
> we can define them differently for different commands (the `ps_*' keys
> come to mind, but that may be a bad example). If we do that, however,
> we probably should think about some standard structure for defining
> styles. Things like multiple styles (separated by commas?), styles
> with values (`[style_a=foo,style_b=bar]' or something like that). If
> this turns out to be useful, I would like change `_tags' to report
> styles in a format that is easier to parse in the calling functions.
When hacking the tags stuff I first thought about storing the
definitions in `compconfig'. The I decided against that because for tags
we need a more convenient way to modify the entries than what
`compconf' offers (where it isn't needed).
After having a look at the keys as listed in the compsys doc, I'm back
again at the idea to combine configuration definitions and tag
definitions -- but this time the other way round. There are only very
few config keys for which it is really completely unnecessary to let
user define them per-command. For several keys it would be rather
weird to define different values, but that never kept us from doing
things.
So, maybe we should try to look at it from this point of view and see
what comes of it... (per-command completer-key? ouch! ;-)
We'll need an easy way to define per-tag defaults and some kind of
agreement about what to do with keys that must not have more than one
value, and we should probably try to make this look less tag-centered
(with styles looking only like some random add-on), etc.
This patch finally adds `_pids' to complete process ids and make the
functions use it. It also adds the `-i' option to `_tags' which means
`immediately' and can be used like `_tags -i foo || return 1' to name
a tag and immediately check if matches of that type are wanted.
Otherwise there isn't much... I just had some time while waiting for a
compiler run.
Bye
Sven
diff -u -r oldcompletion/Base/_describe Completion/Base/_describe
--- oldcompletion/Base/_describe Thu Nov 4 10:33:55 1999
+++ Completion/Base/_describe Thu Nov 4 14:32:45 1999
@@ -23,9 +23,7 @@
# Do the tests. `showd' is set if the descriptions should be shown.
-_tags -c "$cmd" -f "$func" "$type"
-
-_tags || return 1
+_tags -i -c "$cmd" -f "$func" "$type" || return 1
[[ "$tags" = *:${type}\[*describe*\]* ]] && showd=yes
diff -u -r oldcompletion/Base/_values Completion/Base/_values
--- oldcompletion/Base/_values Thu Nov 4 10:33:55 1999
+++ Completion/Base/_values Thu Nov 4 14:32:10 1999
@@ -6,8 +6,7 @@
if ! compvalues -D descr action; then
- _tags value
- _tags || return 1
+ _tags -i value || return 1
compvalues -V noargs args opts
@@ -52,8 +51,7 @@
fi
fi
- _tags argument
- _tags || return 1
+ _tags -i argument || return 1
_description expl "$descr"
diff -u -r oldcompletion/Builtins/_kill Completion/Builtins/_kill
--- oldcompletion/Builtins/_kill Thu Nov 4 10:33:56 1999
+++ Completion/Builtins/_kill Thu Nov 4 14:32:05 1999
@@ -1,24 +1,21 @@
#compdef kill
-local list expl
+local tags list expl
if compset -P 1 -; then
+
+ _tags -i signal || return 1
+
_description expl signal
compadd "$expl[@]" $signals[1,-3]
else
- local tags ret=1
+ local 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
+ [[ "$tags" = *:job:* ]] && _jobs && ret=0
+ [[ "$tags" = *:process:* ]] && _pids && ret=0
(( ret )) || break
done
diff -u -r oldcompletion/Builtins/_pids Completion/Builtins/_pids
--- oldcompletion/Builtins/_pids Thu Nov 4 13:48:35 1999
+++ Completion/Builtins/_pids Thu Nov 4 14:28:00 1999
@@ -0,0 +1,18 @@
+#autoload
+
+# If given the `-m <pattern>' option, this tries to complete only pids
+# of processes whose command line match the `<pattern>'.
+
+local list expl match
+
+if [[ "$1" = -m ]]; then
+ match="${2}*"
+ shift 2
+fi
+
+_description expl 'process ID'
+
+list=("${(@Mr:COLUMNS-1:)${(f@)$(ps ${=compconfig[ps_listargs]:-$=compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*${~match}}")
+
+compadd "$expl[@]" "$@" -ld list - \
+ ${${${(M)${(f)"$(ps $=compconfig[ps_args] 2>/dev/null)"}[2,-1]:#*${~match}}## #}%% *}
diff -u -r oldcompletion/Builtins/_wait Completion/Builtins/_wait
--- oldcompletion/Builtins/_wait Thu Nov 4 10:33:57 1999
+++ Completion/Builtins/_wait Thu Nov 4 13:41:11 1999
@@ -1,18 +1,12 @@
#compdef wait
-local tags list ret=1 expl
+local 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
+ [[ "$tags" = *:job:* ]] && _jobs && ret=0
+ [[ "$tags" = *:process:* ]] && _pids && ret=0
(( ret )) || break
done
diff -u -r oldcompletion/Core/_tags Completion/Core/_tags
--- oldcompletion/Core/_tags Thu Nov 4 10:34:00 1999
+++ Completion/Core/_tags Thu Nov 4 14:31:24 1999
@@ -2,13 +2,14 @@
if (( $# )); then
local cmd="$words[1]" func="$funcstack[2]" defs i tags tag pat style prio
+ local trynow
- while getopts 'c:f:' i; do
- if [[ "$i" = c ]]; then
- cmd="$OPTARG"
- else
- func="$OPTARG"
- fi
+ while getopts 'c:f:i' i; do
+ case "$i" in
+ c) cmd="$OPTARG" ;;
+ f) func="$OPTARG" ;;
+ i) trynow=yes ;;
+ esac
done
shift OPTIND-1
@@ -67,7 +68,7 @@
_prio_names[$funcstack]="$prio"
eval "${prio}=( \"\${(@)tags:#}\" )"
- return 0
+ [[ -z "$trynow" ]] && return 0
fi
local prios="$_prio_names[$funcstack]"
diff -u -r oldcompletion/User/_gdb Completion/User/_gdb
--- oldcompletion/User/_gdb Thu Nov 4 10:34:03 1999
+++ Completion/User/_gdb Thu Nov 4 13:52:25 1999
@@ -21,20 +21,22 @@
_description expl option
compadd "$expl[@]" -QS '' - -symbols\= -exec\= -se\= -core\= -command\= \
-directory\= -cd\= -tty\=
- compadd "$expl[@]" - -help -h -s -e -c -x -d -nx -n -quiet -q -batch \
- -fullname -f -b
+ compadd "$expl[@]" - -help -h -s -e -c -x -d -nx -n -quiet -q \
+ -batch -fullname -f -b
else
prev="$words[CURRENT-1]"
case "$prev" in
- (-d) _files -/ && return 0 ;;
+ (-d) _files -/ && return 0 ;;
(-[csx]) _files && return 0 ;;
- (-e) _description expl executable
- _files "$expl[@]" -g '*(*)' && return 0 ;;
- (-b) _description -V expl 'baud rate'
- compadd "$expl[@]" 0 50 75 110 134 150 200 300 600 1200 1800 2400 4800 \
- 9600 19200 38400 57600 115200 230400 && return 0 ;;
+ (-e) _description expl executable
+ _files "$expl[@]" -g '*(*)' && return 0 ;;
+ (-b) _description -V expl 'baud rate'
+ compadd "$expl[@]" 0 50 75 110 134 150 200 300 600 1200 1800 \
+ 2400 4800 9600 19200 38400 57600 115200 \
+ 230400 && return 0 ;;
esac
+
w=( "${(@)words[2,-1]}" )
while [[ "$w[1]" = -* ]]; do
[[ "$w[1]" = -[decsxb] ]] && shift 1 w
@@ -42,10 +44,8 @@
done
if [[ $#w -gt 1 ]]; then
- _files && ret=0
- _description expl 'process ID'
- list=("${(@M)${(f)$(ps ${=compconfig[ps_listargs]:-$=compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*${w[1]:t}*}")
- compadd "$expl[@]" -ld list - ${${${(M)${(f)"$(ps $=compconfig[ps_args] 2>/dev/null)"}:#*${w[1]:t}*}## #}%% *} && ret=0
+ _files && ret=0
+ _pids -m "${w[1]:t}" && ret=0
return ret
else
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: completion grouping
@ 1999-11-04 9:32 Sven Wischnowsky
1999-11-05 7:20 ` Bart Schaefer
0 siblings, 1 reply; 8+ messages in thread
From: Sven Wischnowsky @ 1999-11-04 9:32 UTC (permalink / raw)
To: zsh-workers
Bart Schaefer wrote:
> On Nov 3, 2:41pm, Sven Wischnowsky wrote:
> } Subject: completion grouping
> }
> } 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
>
> Can I first suggest that we spell out "priorities"? It's not like it's
> going to be typed very often, is it?
The patch below makes the definition of `prios' in completion
functions superfluous by using some $funcstack magic. Should have
thought about this before...
With that, function using `_tags' only have to define the `tags'
parameter, which is probably ok, because they will have to use that
anyway.
> I'm also never sure what to expect from "sorted by priority." In this
> case a smaller number is a higher priority, right? But a negative
> number is treated as bigger than any positive one? That's a bit weird.
> Or am I misunderstanding?
No. Only tags with a positive (or zero) priority are used and then
smaller numbers mean higher priorities (hm, maybe we should change
that if people think that that would feel more natural). Tags with a
negative priority are never reported back at all, i.e. if a user gives
a negative priority he says that he doesn't want to complete that type
of matches.
> ...
>
> } comptag option+='*dvi*=1'
> }
> } the `+=' means that the definition is prepended to the already
> } existing definition
>
> Hrm. I would have expected += to *append* rather than *prepend* (my
> C++ is showing).
Looking at my mail again I noticed that I forgot to mention that `+='
prepends and `=+' appends. With that said this hopefully looks more
sensible ;-)
But I'd like think about changing this function anyway. I.e. I hope to
find a somewhat easier interface. Currently this is still too near to
the way things are stored in `$comptags' and I think the usershouldn't
have to worry/know about the internal representation. On the
completion function side this is already true -- you just call `_tags'
with the names and don't have to think about how `_tags' looks them
up.
Also, I'm thinking about allowing users to use this function to modify
`override_tags', too. So that we don't have to build those pattern-
priority lists ourselves. I think that's another good reason to think
about a better interface.
I also forgot to mention another thing that may be interesting: I
already used the style-stuff for `describe_option' and friends. That
was easy to think about because they allowed definitions on a per-
command basis already. But ther may be other things we currently use
config keys for which may be interesting to turn into styles so that
we can define them differently for different commands (the `ps_*' keys
come to mind, but that may be a bad example). If we do that, however,
we probably should think about some standard structure for defining
styles. Things like multiple styles (separated by commas?), styles
with values (`[style_a=foo,style_b=bar]' or something like that). If
this turns out to be useful, I would like change `_tags' to report
styles in a format that is easier to parse in the calling functions.
Anyway, here is the patch to remove those `prios' parameters. Makes me
feel better.
Bye
Sven
diff -u -r oldcompletion/Base/_arguments Completion/Base/_arguments
--- oldcompletion/Base/_arguments Thu Nov 4 09:05:42 1999
+++ Completion/Base/_arguments Thu Nov 4 10:15:19 1999
@@ -154,7 +154,7 @@
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
+ local tags opts
if comparguments -D descr action; then
if comparguments -O next direct odirect equal; then
diff -u -r oldcompletion/Base/_describe Completion/Base/_describe
--- oldcompletion/Base/_describe Thu Nov 4 09:05:43 1999
+++ Completion/Base/_describe Thu Nov 4 10:15:28 1999
@@ -3,7 +3,7 @@
# This can be used to add options or values with descriptions as matches.
local cmd func opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide
-local prios tags type=value
+local tags type=value
cmd="$words[1]"
func="$funcstack[2]"
diff -u -r oldcompletion/Base/_values Completion/Base/_values
--- oldcompletion/Base/_values Thu Nov 4 09:05:44 1999
+++ Completion/Base/_values Thu Nov 4 10:15:36 1999
@@ -2,7 +2,7 @@
if compvalues -i "$@"; then
- local tags prios noargs args opts descr action expl sep
+ local tags noargs args opts descr action expl sep
if ! compvalues -D descr action; then
diff -u -r oldcompletion/Builtins/_kill Completion/Builtins/_kill
--- oldcompletion/Builtins/_kill Thu Nov 4 09:05:45 1999
+++ Completion/Builtins/_kill Thu Nov 4 10:15:47 1999
@@ -6,7 +6,7 @@
_description expl signal
compadd "$expl[@]" $signals[1,-3]
else
- local prios tags ret=1
+ local tags ret=1
_tags job process
diff -u -r oldcompletion/Builtins/_wait Completion/Builtins/_wait
--- oldcompletion/Builtins/_wait Thu Nov 4 09:05:45 1999
+++ Completion/Builtins/_wait Thu Nov 4 10:15:52 1999
@@ -1,6 +1,6 @@
#compdef wait
-local prios tags list ret=1 expl
+local tags list ret=1 expl
_tags job process
diff -u -r oldcompletion/Core/_files Completion/Core/_files
--- oldcompletion/Core/_files Thu Nov 4 09:05:48 1999
+++ Completion/Core/_files Thu Nov 4 10:16:10 1999
@@ -1,6 +1,6 @@
#autoload
-local opts opt type=file prios tags
+local opts opt type=file tags
opts=()
while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:" opt; do
diff -u -r oldcompletion/Core/_main_complete Completion/Core/_main_complete
--- oldcompletion/Core/_main_complete Thu Nov 4 09:05:48 1999
+++ Completion/Core/_main_complete Thu Nov 4 10:16:03 1999
@@ -17,8 +17,9 @@
# state than the global one for which you are completing.
-local comp post ret=1 _compskip prios tags
+local comp post ret=1 _compskip tags _prio_num=1
typeset -U _offered_tags _tried_tags _failed_tags _used_tags _unused_tags
+typeset -A _prio_names
_offered_tags=()
_tried_tags=()
diff -u -r oldcompletion/Core/_tags Completion/Core/_tags
--- oldcompletion/Core/_tags Thu Nov 4 09:05:49 1999
+++ Completion/Core/_tags Thu Nov 4 10:14:47 1999
@@ -63,17 +63,21 @@
done
done
- prios=( "${(@)tags:#}" )
+ prio="_prio_arr$(( _prio_num++ ))"
+ _prio_names[$funcstack]="$prio"
+ eval "${prio}=( \"\${(@)tags:#}\" )"
return 0
fi
+local prios="$_prio_names[$funcstack]"
+
_failed_tags=( "$_failed_tags[@]" "$_last_tags[@]" )
-(( $#prios )) || return 1
+(( ${(P)#prios} )) || return 1
-tags="${prios[1]}:"
-shift 1 prios
+tags="${${(@P)prios}[1]}:"
+shift 1 "$prios"
_last_tags=( "${(@s.:.)${${tags#:}%:}}" )
_tried_tags=( "$_tried_tags[@]" "$_last_tags[@]" )
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~1999-11-05 15:40 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-11-03 13:41 completion grouping Sven Wischnowsky
1999-11-03 17:12 ` Bart Schaefer
1999-11-04 9:32 Sven Wischnowsky
1999-11-05 7:20 ` Bart Schaefer
1999-11-04 13:50 Sven Wischnowsky
1999-11-04 17:46 ` Bart Schaefer
1999-11-05 10:52 completion grouping (PLEASE read this) Sven Wischnowsky
1999-11-05 14:54 ` completion grouping Oliver Kiddle
1999-11-05 15:40 Sven Wischnowsky
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).