From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20957 invoked from network); 15 Feb 1999 15:09:22 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 15 Feb 1999 15:09:22 -0000 Received: (qmail 20290 invoked by alias); 15 Feb 1999 15:06:17 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 5393 Received: (qmail 20246 invoked from network); 15 Feb 1999 15:06:06 -0000 Message-Id: <9902151446.AA35367@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 From: Peter Stephenson 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 Tel: +39 050 844536 WWW: http://www.ifh.de/~pws/ Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy