zsh-workers
 help / color / mirror / code / Atom feed
* 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 13:50 completion grouping 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-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  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

* Re: completion grouping
  1999-11-03 13:41 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

* 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

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-04 13:50 completion grouping Sven Wischnowsky
1999-11-04 17:46 ` Bart Schaefer
  -- strict thread matches above, loose matches on Subject: below --
1999-11-05 15:40 Sven Wischnowsky
1999-11-05 10:52 completion grouping (PLEASE read this) Sven Wischnowsky
1999-11-05 14:54 ` completion grouping Oliver Kiddle
1999-11-04  9:32 Sven Wischnowsky
1999-11-05  7:20 ` Bart Schaefer
1999-11-03 13:41 Sven Wischnowsky
1999-11-03 17:12 ` Bart Schaefer

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).