zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: 3.1.5-pws-8: dumping completions for speed
@ 1999-02-15 14:46 Peter Stephenson
  0 siblings, 0 replies; 3+ messages in thread
From: Peter Stephenson @ 1999-02-15 14:46 UTC (permalink / raw)
  To: Zsh hackers list

The following patch adds a file `dump' to the Functions/Completions
directory.  This dumps out all the state information which the `init' file
there has produced, so that for subsequent shell initialisations it can all
be read in in one go.  This speeds up my total shell startup time including
the new completions by a factor of around two, though I haven't timed it
properly.  You just dot it and put the out put in $foo.dump, where $foo is
where the file called Functions/Completions/init in the distribution lives
in your setup; sourcing $foo finds $foo.dump automatically.

A few slightly icky things:

1) you have to call it straight after running init, since the state
information changes after #array things have been loaded;

2) every time you add a new completion you have to remove init.dump
and remake it --- this is a generic problem, but made worse by 1);

3) dot-files don't have local scope, so I changed the variables in init as
well as dump to silly names and then unset them explicitly --- getting the
options right is hard for the same reason --- should { ... } maybe allow
both option and parameter localisation?

4) I just made it check for $0.dump in init, so if it had to search the
path for init, it won't find init.dump (that's why perl sets $0 to a full
path name).

On the matter of context-sensitive completions: it looks neat, but I'd be
very worried about losing command-based completion since (like the MH
example I gave) it makes it very easy to keep track of all the bits and
what commands they apply to.  If context information is simply intended as
an enhancement to that, that's fine.  Then the market can choose whether
__find looks like Functions/Completion/__find or Functions/Comp/__find .
(I don't envisage having both of those in the pws-* distributions, but I
presume they would be merged at some point.)

--- Functions/Completion/dump.bk	Mon Feb 15 15:19:57 1999
+++ Functions/Completion/dump	Mon Feb 15 15:20:17 1999
@@ -0,0 +1,108 @@
+# This is a file to be sourced to dump the definitions for new-style
+# completion defined by 'init' in the same directory.  For best results,
+# it should be run immediately after init, before any of the completions
+# have been autoloaded.  The output should be directed into the "init.dump"
+# in the same directory as init.  If you rename init, just stick .dump onto
+# the end of whatever you have called it and put it in the same directory.
+#
+# You will need to update the dump every time you add a new completion.
+# To do this, simply remove the .dump file, start a new shell, and
+# create the .dump file as before.
+#
+# It relies on KSH_ARRAYS not being set.
+
+
+# First dump the arrays comps, patcomps and keycomps; the middle one
+# is an ordinary array, the other two are associative.  The
+# quoting hieroglyphyics ensure that a single quote inside a
+# variable is itself correctly quoted.
+
+print "comps=("
+for __d_f in ${(k)comps}; do
+    print -r - "'${__d_f//\'/'\\''}'" "'${comps[$__d_f]//\'/'\\''}'"
+done
+print ")"
+
+if (( $#patcomps )); then
+  print "\npatcomps=("
+  for __d_f in $patcomps; do
+    print -r - "'${__d_f//\'/'\\''}'"
+  done
+  print ")"
+fi
+
+if (( $#keycomps )); then
+  print "\nkeycomps=("
+  for __d_f in ${(k)keycomps}; do
+    print -r - "'${__d_f//\'/'\\''}'" "'${keycomps[$__d_f]//\'/'\\''}'"
+  done
+  print ")\n"
+  # Here, we need both the zle -C's and the bindkey's to recreate.
+  __d_bks=()
+  zle -lL |
+  while read -A __d_line; do
+    if [[ ${__d_line[5]} = __main_key_complete ]]; then
+      print ${__d_line}
+      __d_bks=($__d_bks ${__d_line[3]})
+    fi
+  done
+  bindkey |
+  while read -A __d_line; do
+    if [[ ${__d_line[2]} = (${(j.|.)~__d_bks}) ]]; then
+      print "bindkey '${__d_line[1][2,-2]}' ${__d_line[2]}"
+    fi
+  done
+fi
+
+print
+
+
+# Autoloads: whence -w produces "__d_foo: function", so look for
+# all functions beginning with `__'.
+
+__d_als=($(whence -wm '__*' |
+while read -A __d_line; do
+  [[ ${__d_line[2]} = function ]] && print ${__d_line[1]%:}
+done))
+
+# print them out:  about six to a line looks neat
+
+while (( $#__d_als )); do
+  print -n autoload
+  for (( _i = 0; _i < 6; _i++ )); do
+    if (( $#__d_als )); then
+      print -n " $__d_als[1]"
+      shift __d_als
+    fi
+  done
+  print
+done
+
+print
+
+
+# Finally, the new style functions:  we look for the ones which init
+# has just bound and create bindkey and zle -C statements to remake
+# them.
+
+typeset -A __d_zle
+__d_bks=''
+
+bindkey | while read -A __d_line; do
+	    if [[ "$__d_line[2]" = \
+__complete_(expand-or-complete(-prefix|)|complete-word|list-choices\
+|delete-char-or-list|menu-(expand-or-|)complete|reverse-menu-complete) ]]; then
+# The zle statements are collected as an assoc array, to avoid generating
+# too many.
+	      __d_zle[$__d_line[2]]="zle -C $__d_line[2] \
+${__d_line[2]#__complete_} __main_complete"
+# The bindkey's are just collected as a string.
+	      __d_bks="$__d_bks
+bindkey '${__d_line[1][2,-2]}' ${__d_line[2]}"
+	    fi
+	  done
+
+print -l ${(ov)__d_zle}
+print "$__d_bks"
+
+unset __d_line __d_zle __d_bks __d_als __d_f
--- Functions/Completion/init.bk	Sat Feb 13 13:55:12 1999
+++ Functions/Completion/init	Mon Feb 15 15:20:17 1999
@@ -51,6 +51,8 @@
 #
 # Note that no white space is allowed between the `#' and the rest of
 # the string.
+#
+# See the file `dump' for how to speed up initialiation.
 
 
 # An associative array for completions definitions. The keys of the entries
@@ -207,47 +209,49 @@
 }
 
 
-# Now we make the files automatically autoloaded.
-
-local dir file line func
-
-for dir in $fpath; do
-  [[ $dir = . ]] && continue
-  for file in $dir/__*~*~(N); do
-    read -rA line < $file
-    func=$line[1]
-    shift line
-    if [[ $func = '#function' ]]; then
-      defcomp -a ${file:t} "${line[@]}"
-    elif [[ $func = '#array' ]]; then
-      defcomp " $file" "${line[@]}"
-    elif [[ $func = '#pattern-function' ]]; then
-      defpatcomp -a ${file:t} "${line[@]}"
-    elif [[ $func = '#pattern-array' ]]; then
-      defcomp " $file" "${line[@]}"
-    elif [[ $func = '#key-function' ]]; then
-      defkeycomp -a "${file:t}" "${line[@]}"
-    elif [[ $func = '#key-array' ]]; then
-      defkeycomp " $file" "${line[@]}"
-    elif [[ $func = '#helper' ]]; then
-      autoload ${file:t}
-    fi
+if [[ -f $0.dump ]]; then
+  . $0.dump
+else
+  # Now we make the files automatically autoloaded.
+  for __i_dir in $fpath; do
+    [[ $__i_dir = . ]] && continue
+    for __i_file in $__i_dir/__*~*~(N); do
+      read -rA __i_line < $__i_file
+      func=$__i_line[1]
+      shift __i_line
+      if [[ $func = '#function' ]]; then
+	defcomp -a ${__i_file:t} "${__i_line[@]}"
+      elif [[ $func = '#array' ]]; then
+	defcomp " $__i_file" "${__i_line[@]}"
+      elif [[ $func = '#pattern-function' ]]; then
+	defpatcomp -a ${__i_file:t} "${__i_line[@]}"
+      elif [[ $func = '#pattern-array' ]]; then
+	defcomp " $__i_file" "${__i_line[@]}"
+      elif [[ $func = '#key-function' ]]; then
+	defkeycomp -a "${__i_file:t}" "${__i_line[@]}"
+      elif [[ $func = '#key-array' ]]; then
+	defkeycomp " $__i_file" "${__i_line[@]}"
+      elif [[ $func = '#helper' ]]; then
+	autoload ${__i_file:t}
+      fi
+    done
   done
-done
 
+  # Finally we make all this be called by changing the key bindings.
 
-# Finally we make all this be called by changing the key bindings.
+  bindkey | while read -A __i_line; do
+	      if [[ "$__i_line[2]" = complete-word ||
+		"$__i_line[2]" = delete-char-or-list ||
+		"$__i_line[2]" = expand-or-complete ||
+		"$__i_line[2]" = expand-or-complete-prefix ||
+		"$__i_line[2]" = list-choices ||
+		"$__i_line[2]" = menu-complete ||
+		"$__i_line[2]" = menu-expand-or-complete ||
+		"$__i_line[2]" = reverse-menu-complete ]]; then
+		zle -C __complete_$__i_line[2] $__i_line[2] __main_complete
+		bindkey "${__i_line[1][2,-2]}" __complete_$__i_line[2]
+	      fi
+	    done
 
-bindkey | while read -A line; do
-            if [[ "$line[2]" = complete-word ||
-	    	  "$line[2]" = delete-char-or-list ||
-	    	  "$line[2]" = expand-or-complete ||
-	    	  "$line[2]" = expand-or-complete-prefix ||
-	    	  "$line[2]" = list-choices ||
-	    	  "$line[2]" = menu-complete ||
-	    	  "$line[2]" = menu-expand-or-complete ||
-	    	  "$line[2]" = reverse-menu-complete ]]; then
-              zle -C __complete_$line[2] $line[2] __main_complete
-              bindkey "${line[1][2,-2]}" __complete_$line[2]
-            fi
-          done
+  unset __i_dir __i_line __i_file
+fi

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


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

* Re:  PATCH: 3.1.5-pws-8: dumping completions for speed
@ 1999-02-16 15:15 Sven Wischnowsky
  0 siblings, 0 replies; 3+ messages in thread
From: Sven Wischnowsky @ 1999-02-16 15:15 UTC (permalink / raw)
  To: zsh-workers


I wrote:

> Peter Stephenson wrote:
>
> > 4) I just made it check for $0.dump in init, so if it had to search the
> > path for init, it won't find init.dump (that's why perl sets $0 to a full
> > path name).
> 
> How about making this the default, but if the user has set a parameter 
> (COMPDUMP or something) and that contains the name of a file, source
> that one?

The patch below adds this (set COMPDUMP to the file name you want to
use before dotting init, $0.dump is the default).

It also adds an experimental auto-dumping. If the parameter AUTODUMP
is set to `yes' when init is dotted, it will automatically dump the
state on first invocation or if it thinks the number completion files
has changed. Hm, does this look like the right thing?

Bye
 Sven

diff -u of/Completion/dump Functions/Completion/dump
--- of/Completion/dump	Tue Feb 16 16:04:04 1999
+++ Functions/Completion/dump	Tue Feb 16 16:13:05 1999
@@ -11,6 +11,14 @@
 #
 # It relies on KSH_ARRAYS not being set.
 
+# Print the number of files used for completion. This is used in init
+# to see if auto-dump should re-dump the dump-file.
+
+__d_files=( ${^~fpath}/__*~*~ )
+
+print "#files: $#__d_files"
+
+unset __d_files
 
 # First dump the arrays comps, patcomps and keycomps; the middle one
 # is an ordinary array, the other two are associative.  The
diff -u of/Completion/init Functions/Completion/init
--- of/Completion/init	Tue Feb 16 15:03:00 1999
+++ Functions/Completion/init	Tue Feb 16 16:10:40 1999
@@ -208,10 +208,20 @@
   fi
 }
 
+__i_files=( ${^~fpath}/__*~*~ )
+__i_initname=$0
+__i_dumpname=${COMPDUMP-$0.dump}
+__i_done=''
 
-if [[ -f $0.dump ]]; then
-  . $0.dump
-else
+if [[ -f $__i_dumpname ]]; then
+  read -rA __i_line < $__i_dumpname
+  if [[ "$AUTODUMP" != yes || $__i_line[2] -eq $#__i_files ]]; then
+    builtin . $__i_dumpname
+    __i_done=yes
+  fi
+  unset __i_line
+fi
+if [[ -z "$__i_done" ]]; then
   # Now we make the files automatically autoloaded.
   for __i_dir in $fpath; do
     [[ $__i_dir = . ]] && continue
@@ -254,4 +264,8 @@
 	    done
 
   unset __i_dir __i_line __i_file
+
+  [[ "$AUTODUMP" = yes ]] && builtin . ${__i_initname:h}/dump > $__i_dumpname
 fi
+
+unset __i_files __i_initname __i_dumpname __i_done

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


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

* Re:  PATCH: 3.1.5-pws-8: dumping completions for speed
@ 1999-02-16 14:23 Sven Wischnowsky
  0 siblings, 0 replies; 3+ messages in thread
From: Sven Wischnowsky @ 1999-02-16 14:23 UTC (permalink / raw)
  To: zsh-workers


Peter Stephenson wrote:

> The following patch adds a file `dump' to the Functions/Completions
> directory.  This dumps out all the state information which the `init' file
> there has produced, so that for subsequent shell initialisations it can all
> be read in in one go.  This speeds up my total shell startup time including
> the new completions by a factor of around two, though I haven't timed it
> properly.  You just dot it and put the out put in $foo.dump, where $foo is
> where the file called Functions/Completions/init in the distribution lives
> in your setup; sourcing $foo finds $foo.dump automatically.

Yes, it was inacceptably slow. I had some problems with this, though:
in one place in `dump' print wasn't used with a `-' which failed for
me because in the `${(ov)...}' that came after it I need a `@' -- see
the patch below, which adds lots of `-'s, just to make sure... (haven't
checked it, but I guess in most places they are not needed). Also in
`init' we probably should use `builtin .' since users may have an
alias/function for it.

> ...
> 
> 4) I just made it check for $0.dump in init, so if it had to search the
> path for init, it won't find init.dump (that's why perl sets $0 to a full
> path name).

How about making this the default, but if the user has set a parameter 
(COMPDUMP or something) and that contains the name of a file, source
that one?

Bye
 Sven

diff -u of/Completion/dump Functions/Completion/dump
--- of/Completion/dump	Tue Feb 16 15:03:00 1999
+++ Functions/Completion/dump	Tue Feb 16 15:15:43 1999
@@ -42,7 +42,7 @@
   zle -lL |
   while read -A __d_line; do
     if [[ ${__d_line[5]} = __main_key_complete ]]; then
-      print ${__d_line}
+      print - ${__d_line}
       __d_bks=($__d_bks ${__d_line[3]})
     fi
   done
@@ -62,7 +62,7 @@
 
 __d_als=($(whence -wm '__*' |
 while read -A __d_line; do
-  [[ ${__d_line[2]} = function ]] && print ${__d_line[1]%:}
+  [[ ${__d_line[2]} = function ]] && print - ${__d_line[1]%:}
 done))
 
 # print them out:  about six to a line looks neat
@@ -102,7 +102,7 @@
 	    fi
 	  done
 
-print -l ${(ov)__d_zle}
-print "$__d_bks"
+print -l - "${(@ov)__d_zle}"
+print - "$__d_bks"
 
 unset __d_line __d_zle __d_bks __d_als __d_f
diff -u of/Completion/init Functions/Completion/init
--- of/Completion/init	Tue Feb 16 15:03:00 1999
+++ Functions/Completion/init	Tue Feb 16 15:17:34 1999
@@ -210,7 +210,7 @@
 
 
 if [[ -f $0.dump ]]; then
-  . $0.dump
+  builtin . $0.dump
 else
   # Now we make the files automatically autoloaded.
   for __i_dir in $fpath; do

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


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

end of thread, other threads:[~1999-02-16 15:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-02-15 14:46 PATCH: 3.1.5-pws-8: dumping completions for speed Peter Stephenson
1999-02-16 14:23 Sven Wischnowsky
1999-02-16 15:15 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).