zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: completion functions
@ 1999-08-26  9:28 Sven Wischnowsky
  1999-08-27 17:24 ` Nested associations (was Re: PATCH: completion functions) Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Sven Wischnowsky @ 1999-08-26  9:28 UTC (permalink / raw)
  To: zsh-workers


This tries to make `_arguments' a bit faster by caching the results of 
parsing its arguments. The it makes `_find' use `_arguments' and then
there is a fixlet for `_x_font' (forgot to make the cache global).

One comment about the caching: I'd like to use `_arguments' in much
more functions (even rewriting some of the `{Builtins,User}/*'
functions we have). But then a single cache is pretty useless. But if
we were able to put arrays and associations into associations, we
could have command-specific caches. Internally, this probably wouldn't
be too hard to implement, I think, but if I remember correctly, Bart
was against it and explicitly disallowed this. Maybe if we just tell
the users that associative arrays can act as name-spaces? (In other
words: Bart, what was the reason that you was against it? Or weren't
you against it and my memory is failing?)

Bye
 Sven

diff -u -r oc/Base/_arguments Completion/Base/_arguments
--- oc/Base/_arguments	Wed Aug 25 14:59:03 1999
+++ Completion/Base/_arguments	Thu Aug 26 11:20:00 1999
@@ -14,119 +14,144 @@
 typeset -A opts dopts odopts
 typeset -A oneshot
 
-# See if we are using single-letter options.
+# Fill the cache if we were called with different arguments.
 
-if [[ "$1" = -s ]]; then
-  shift
-  single=yes
-fi
+if [[ "$*" != "$_args_cache_descr" ]]; then
+  _args_cache_descr="$*"
 
-# See if we support long options, too.
+  unset _args_cache_{opts,dopts,odopts,oneshot}
+  typeset -gA _args_cache_{opts,dopts,odopts,oneshot}
 
-nth=$argv[(I)--]
-if (( nth )); then
-  long=( "${(@)argv[nth+1,-1]}" )
-  argv=("${(@)argv[1,nth-1]}")
-else
-  long=()
-fi
+  unset _args_cache_{long,single,rest,args,sopts,soptseq,soptseq1}
 
-# Now parse the arguments...
+  # See if we are using single-letter options.
+
+  if [[ "$1" = -s ]]; then
+    shift
+    _args_cache_single=yes
+  fi
 
-args=()
-nth=1
-while (( $# )); do
-
-  # This describes a one-shot option.
-
-  if [[ "$1" = [-+]* ]]; then
-    if [[ "$1" = *:* ]]; then
-
-      # If the option name ends in a `-', the first argument comes
-      # directly after the option, if it ends in a `+', the first
-      # argument *may* come directly after the option, otherwise it
-      # is in the next word.
-
-      if [[ "$1" = [^:]##-:* ]]; then
-	tmp="${${1%%:*}[1,-2]}"
-        dopts[$tmp]="${1#*:}"
-      elif [[ "$1" = [^:]##+:* ]]; then
-	tmp="${${1%%:*}[1,-2]}"
-        odopts[$tmp]="${1#*:}"
+  # See if we support long options, too.
+
+  nth=$argv[(I)--]
+  if (( nth )); then
+    _args_cache_long=( "${(@)argv[nth+1,-1]}" )
+    _args_cache_long_nth=$(( nth - 1 ))
+  else
+    _args_cache_long=()
+  fi
+
+  # Now parse the arguments...
+
+  args=()
+  nth=1
+  while (( $# )); do
+
+    # This describes a one-shot option.
+
+    if [[ "$1" = [-+]* ]]; then
+      if [[ "$1" = *:* ]]; then
+
+        # If the option name ends in a `-', the first argument comes
+        # directly after the option, if it ends in a `+', the first
+        # argument *may* come directly after the option, otherwise it
+        # is in the next word.
+
+        if [[ "$1" = [^:]##-:* ]]; then
+  	  tmp="${${1%%:*}[1,-2]}"
+          _args_cache_dopts[$tmp]="${1#*:}"
+        elif [[ "$1" = [^:]##+:* ]]; then
+  	  tmp="${${1%%:*}[1,-2]}"
+          _args_cache_odopts[$tmp]="${1#*:}"
+        else
+          tmp="${1%%:*}"
+          _args_cache_opts[$tmp]="${1#*:}"
+        fi
       else
-        tmp="${1%%:*}"
-        opts[$tmp]="${1#*:}"
+        tmp="$1"
+        _args_cache_opts[$tmp]=''
       fi
-    else
-      tmp="$1"
-      opts[$tmp]=''
-    fi
-    oneshot[$tmp]=yes
-  elif [[ "$1" = \*[-+]* ]]; then
+      _args_cache_oneshot[$tmp]=yes
+    elif [[ "$1" = \*[-+]* ]]; then
 
-    # The same for options that may appear more than once.
+      # The same for options that may appear more than once.
 
-    if [[ "$1" = *:* ]]; then
-      if [[ "$1" = [^:]##-:* ]]; then
-        tmp="${${1[2,-1]%%:*}[1,-2]}"
-        dopts[$tmp]="${1#*:}"
-      elif [[ "$1" = [^:]##+:* ]]; then
-        tmp="${${1[2,-1]%%:*}[1,-2]}"
-        odopts[$tmp]="${1#*:}"
+      if [[ "$1" = *:* ]]; then
+        if [[ "$1" = [^:]##-:* ]]; then
+          tmp="${${1[2,-1]%%:*}[1,-2]}"
+          _args_cache_dopts[$tmp]="${1#*:}"
+        elif [[ "$1" = [^:]##+:* ]]; then
+          tmp="${${1[2,-1]%%:*}[1,-2]}"
+          _args_cache_odopts[$tmp]="${1#*:}"
+        else
+          tmp="${1[2,-1]%%:*}"
+          _args_cache_opts[$tmp]="${1#*:}"
+        fi
       else
-        tmp="${1[2,-1]%%:*}"
-        opts[$tmp]="${1#*:}"
+        tmp="${1[2,-1]}"
+        _args_cache_opts[$tmp]=''
       fi
-    else
-      tmp="${1[2,-1]}"
-      opts[$tmp]=''
-    fi
-    unset "oneshot[$tmp]"
-  elif [[ "$1" = \*::* ]]; then
+      unset "_args_cache_oneshot[$tmp]"
+    elif [[ "$1" = \*::* ]]; then
 
-    # This is `*:...', describing `all other arguments', with argument 
-    # range restriction.
+      # This is `*:...', describing `all other arguments', with argument 
+      # range restriction.
 
-    if [[ "$1" = \*:::* ]]; then
-      rest="*${1[3,-1]}"
-    else
-      rest="$1"
-    fi
-  elif [[ "$1" = \*:* ]]; then
+      if [[ "$1" = \*:::* ]]; then
+        _args_cache_rest="*${1[3,-1]}"
+      else
+        _args_cache_rest="$1"
+      fi
+    elif [[ "$1" = \*:* ]]; then
 
-    # This is `*:...', describing `all other arguments'.
+      # This is `*:...', describing `all other arguments'.
 
-    rest="${1[3,-1]}"
-  elif [[ "$1" = :* ]]; then
+      _args_cache_rest="${1[3,-1]}"
+    elif [[ "$1" = :* ]]; then
 
-    # This is `:...', describing `the next argument'.
+      # This is `:...', describing `the next argument'.
 
-    args[nth++]="${1#*:}"
-  else
+      _args_cache_args[nth++]="${1#*:}"
+    else
 
-    # And this is `n:...', describing the `n'th argument.
+      # And this is `n:...', describing the `n'th argument.
 
-    args[${1%%:*}]="${1#*:}"
-    nth=$(( ${1%%:*} + 1 ))
-  fi
-  shift
-done
+      _args_cache_args[${1%%:*}]="${1#*:}"
+      nth=$(( ${1%%:*} + 1 ))
+    fi
+    shift
+  done
 
-if [[ -n "$single" ]]; then
-  soptseq="${(@j::)${(@M)${(@k)opts[(R)]}:#[-+]?}#[-+]}"
-  if [[ -n "$soptseq" ]]; then
-    soptseq="[$soptseq]#"
-    soptseq1="$soptseq#"
+  if [[ -n "$_args_cache_single" ]]; then
+    _args_cache_soptseq="${(@j::)${(@M)${(@k)opts[(R)]}:#[-+]?}#[-+]}"
+    if [[ -n "$_args_cache_soptseq" ]]; then
+      _args_cache_soptseq="[$_args_cache_soptseq]#"
+      _args_cache_soptseq1="$_args_cache_soptseq#"
+    else
+      _args_cache_soptseq=''
+      _args_cache_soptseq1=''
+    fi
+    _args_cache_sopts="${(@j::)${(@M)${(@k)opts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odopts}:#[-+]?}#[-+]}"
   else
-    soptseq=''
-    soptseq1=''
+    _args_cache_soptseq=''
+    _args_cache_soptseq1=''
+    _args_cache_sopts=''
   fi
-  sopts="${(@j::)${(@M)${(@k)opts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odopts}:#[-+]?}#[-+]}"
-else
-  soptseq=''
-  soptseq1=''
-  sopts=''
 fi
+
+soptseq="$_args_cache_soptseq"
+soptseq1="$_args_cache_soptseq1"
+sopts="$_args_cache_sopts"
+args=( "$_args_cache_args[@]" )
+rest="$_args_cache_rest"
+opts=( "${(@kv)_args_cache_opts}" )
+dopts=( "${(@kv)_args_cache_dopts}" )
+odopts=( "${(@kv)_args_cache_odopts}" )
+oneshot=( "${(@kv)_args_cache_oneshot}" )
+single="$_args_cache_single"
+long=( "$_args_cache_long[@]" )
+
+argv=( "${(@)argv[1,_args_cache_long_nth]}" )
 
 # Parse the command line...
 
diff -u -r oc/User/_find Completion/User/_find
--- oc/User/_find	Wed Aug 25 14:59:13 1999
+++ Completion/User/_find	Thu Aug 26 10:58:55 1999
@@ -1,31 +1,59 @@
 #compdef find
 
-local prev="$words[CURRENT-1]" expl
-
-if compset -N '-(ok|exec)' '\;'; then
-  _normal
-elif [[ "$PREFIX" = -* ]]; then
-  _description expl option
-  compadd "$expl[@]" - -daystart -{max,min,}depth -follow -noleaf \
-    -version -xdev -{a,c,}newer -{a,c,m}{min,time} -empty -false \
-    -{fs,x,}type -gid -inum -links -{i,}{l,}name -{no,}{user,group} \
-    -path -perm -regex -size -true -uid -used -exec -{f,}print{f,0,} \
-    -ok -prune -ls
-elif [[ CURRENT -eq 2 ]]; then
-  local ret=1
-
-  _description expl directory
-  compgen "$expl[@]" -g '. ..' && ret=0
-  _files -/ && ret=0
-
-  return ret
-elif [[ "$prev" = -((a|c|)newer|fprint(|0|f)) ]]; then
-  _files
-elif [[ "$prev" = -fstype ]]; then
-  _description expl 'file system type'
-  compadd "$expl[@]" ufs 4.2 4.3 nfs tmp mfs S51K S52K
-elif [[ "$prev" = -group ]]; then
-  _groups
-elif [[ "$prev" = -user ]]; then
-  _users
-fi
+_arguments \
+  '-daystart' \
+  '-depth' \
+  '-follow' \
+  '-help' \
+  '-maxdepth:maximum search depth:' \
+  '-mindepth:minimum search depth:' \
+  '-mount' \
+  '-noleaf' \
+  '-version' \
+  '-xdev' \
+  '-amin:access time (minutes):' \
+  '-cmin:inode change time (minutes):' \
+  '-mmin:modification time (minutes):' \
+  '-atime:access time (days):' \
+  '-ctime:inode change time (days):' \
+  '-mtime:modification time (days):' \
+  '-anewer:file to compare (access time):_files' \
+  '-cnewer:file to compare (inode change time):_files' \
+  '-newer:file to compare (modification time):_files' \
+  '-used:access after inode change (days):' \
+  '-empty' \
+  '-false' \
+  '-fstype:filesystem type:(ufs 4.2 4.3 nfs tmp mfs S51K S52K)' \
+  '-gid:numeric group ID:' \
+  '-group:group:_groups' \
+  '-uid:numeric user ID:' \
+  '-user:user:_users' \
+  '-lname:link pattern to search:' \
+  '-ilname:link pattern to search (case insensitive):' \
+  '-name:name pattern to search:' \
+  '-iname:name pattern to search (case insensitive):' \
+  '-path:path pattern to search:' \
+  '-ipath:path pattern to search (case insensitive):' \
+  '-regex:regular expression to search:' \
+  '-iregex:regular expression to search (case insensitive):' \
+  '-inum:inode number:' \
+  '-links:number of links:' \
+  '-nouser' \
+  '-nogroup' \
+  '-perm:file permission bits:' \
+  '-size:file size:' \
+  '-true' \
+  '-type:file type:(b c d p f l s)' \
+  '-xtype:file type:(b c d p f l s)' \
+  '-exec:program: _command_names -e:*\;::program arguments: _normal' \
+  '-ok:program: _command_names -e:*\;::program arguments: _normal' \
+  '-fls:output file:_files' \
+  '-fprint:output file:_files' \
+  '-fprint0:output file:_files' \
+  '-fprintf:output file:_files:output format:' \
+  '-print' \
+  '-print0' \
+  '-printf:output format:' \
+  '-prune' \
+  '-ls' \
+  '*:directory:_files -/'
diff -u -r oc/X/_x_font Completion/X/_x_font
--- oc/X/_x_font	Wed Aug 25 14:59:16 1999
+++ Completion/X/_x_font	Thu Aug 26 10:23:50 1999
@@ -5,7 +5,7 @@
 # This *has* to be improved some day...
 
 if (( ! $+_font_cache )); then
-  typeset -U _font_cache
+  typeset -gU _font_cache
 
  _font_cache=( "${(@)^${(@f)$(xlsfonts)}%%--*}--" )
 fi

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Nested associations (was Re: PATCH: completion functions)
  1999-08-26  9:28 PATCH: completion functions Sven Wischnowsky
@ 1999-08-27 17:24 ` Bart Schaefer
  0 siblings, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 1999-08-27 17:24 UTC (permalink / raw)
  To: zsh-workers

On Aug 26, 11:28am, Sven Wischnowsky wrote:
} Subject: PATCH: completion functions
}
} [If] we were able to put arrays and associations into associations, we
} could have command-specific caches. Internally, this probably wouldn't
} be too hard to implement, I think, but if I remember correctly, Bart
} was against it and explicitly disallowed this. Maybe if we just tell
} the users that associative arrays can act as name-spaces? (In other
} words: Bart, what was the reason that you was against it? Or weren't
} you against it and my memory is failing?)

I wasn't against it; in fact I particularly arranged the storage for
associative arrays to allow for it to be added in the future.  There are
a number of reasons why I didn't do more with it:

I thought it would be better to have it thoroughly tested and working
one level deep before allowing nesting.

I think we need better assignment syntax before allowing nesting; how
do you copy one nested AA to another?

Similarly, I can't decide how expansion should behave.  What happens when
you refer to the entire tree structure with $outermostname ?  What about
${(kv)outermostname}; do the flags propagate to the nested arrays?  Why?
When you ask for $outermostname[(r)...], how is the pattern compared to
nested sub-arrays?  And so on.

Internally, the code is not well-organized to re-enter parameter table
lookups during processing of multiple subscripts.  As with much of zsh,
the parameter lookup code depends on a global value, which I hacked to be
saved/altered/restored during associative array operations.  By the time
you're past the first level of subscripting, it's unclear (to me, anyway)
whether you still have all the necessary data to swap into the `paramtab'
global for the next level of lookup.

Finally, you can get much the same effect either by careful choice of key
names or by indirection with ${(P)...}, so it didn't seem to be necessary.

Why can't you do e.g. _args_cache_dopts[$command.$tmp]="${1#*:}" where
$command comes e.g. from passing the name of the current command to the
call to _arguments from the other completion functions?

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Nested associations (was Re: PATCH: completion functions)
@ 1999-08-30  9:19 Sven Wischnowsky
  0 siblings, 0 replies; 3+ messages in thread
From: Sven Wischnowsky @ 1999-08-30  9:19 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> On Aug 26, 11:28am, Sven Wischnowsky wrote:
> } Subject: PATCH: completion functions
> }
> } [If] we were able to put arrays and associations into associations, we
> } could have command-specific caches. Internally, this probably wouldn't
> } be too hard to implement, I think, but if I remember correctly, Bart
> } was against it and explicitly disallowed this. Maybe if we just tell
> } the users that associative arrays can act as name-spaces? (In other
> } words: Bart, what was the reason that you was against it? Or weren't
> } you against it and my memory is failing?)
> 
> I wasn't against it; in fact I particularly arranged the storage for
> associative arrays to allow for it to be added in the future.  There are
> a number of reasons why I didn't do more with it:
> 
> I thought it would be better to have it thoroughly tested and working
> one level deep before allowing nesting.
> 
> I think we need better assignment syntax before allowing nesting; how
> do you copy one nested AA to another?
> 
> Similarly, I can't decide how expansion should behave.  What happens when
> you refer to the entire tree structure with $outermostname ?  What about
> ${(kv)outermostname}; do the flags propagate to the nested arrays?  Why?
> When you ask for $outermostname[(r)...], how is the pattern compared to
> nested sub-arrays?  And so on.

Ok, I didn't think about some of these, sorry. (Now I have some things 
to think about...)

> Internally, the code is not well-organized to re-enter parameter table
> lookups during processing of multiple subscripts.  As with much of zsh,
> the parameter lookup code depends on a global value, which I hacked to be
> saved/altered/restored during associative array operations.  By the time
> you're past the first level of subscripting, it's unclear (to me, anyway)
> whether you still have all the necessary data to swap into the `paramtab'
> global for the next level of lookup.
> 
> Finally, you can get much the same effect either by careful choice of key
> names or by indirection with ${(P)...}, so it didn't seem to be necessary.
> 
> Why can't you do e.g. _args_cache_dopts[$command.$tmp]="${1#*:}" where
> $command comes e.g. from passing the name of the current command to the
> call to _arguments from the other completion functions?

Because some of them are arrays or assocs. On the expansion side we
could use `${(P)...}', of course (and I'm tempted to implement that),
but since we changed the code to disallow expansions on the left hand
side of assignments we would have to use lots of `eval's there -- and
I was just too lazy to write that (and I don't like it, I liked
being able to do `$foo=...').

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~1999-08-30  9:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-08-26  9:28 PATCH: completion functions Sven Wischnowsky
1999-08-27 17:24 ` Nested associations (was Re: PATCH: completion functions) Bart Schaefer
1999-08-30  9:19 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).