zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <pws@ibmth.df.unipi.it>
To: zsh-workers@sunsite.auc.dk (Zsh hackers list)
Subject: PATCH: 3.1.5-pws-8: dumping completions for speed
Date: Mon, 15 Feb 1999 15:46:31 +0100	[thread overview]
Message-ID: <9902151446.AA35367@ibmth.df.unipi.it> (raw)

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


             reply	other threads:[~1999-02-15 15:09 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-02-15 14:46 Peter Stephenson [this message]
1999-02-16 14:23 Sven Wischnowsky
1999-02-16 15:15 Sven Wischnowsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9902151446.AA35367@ibmth.df.unipi.it \
    --to=pws@ibmth.df.unipi.it \
    --cc=zsh-workers@sunsite.auc.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).