Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: new completion cleanup



Peter Stephenson wrote:

> Another issue: ordering of pattern completions.  I think this can already
> be done quite naturally.  `init' (should we turn the files into compinit
> and compdump btw?) stores the patterns in $patcomps in the order it finds
> them in the directory, which is globbing order, which is alphabetic, and
> `dump' preserves this order, and _normal goes through them in the same
> order.

Here is a case where this ordering makes things fail: some random user 
has `fpath=(.../myfuncs .../stdfuncs)'. In `myfuncs' is a file `_foo'
defining a completion for `foo'. In `stdfuncs' is a file `_bar'
defining another completion for `foo'. The code in init will find
`_foo' and store `comps[foo]=_foo', later it finds `_bar' and changes
`comps[foo]=_bar'. Certainly not what one wants. The patch below fixes 
this by making `defcomp' accept the option `-n' which means that the
definition is stored only if there is no older definition for the
command name. (One day I will have to clean up the option handling in
these functions and in `_path_files', for now, the `-n' has to come
before the `-a'.)

The patch also makes `init' temporarily set (and later restore)
`extendedglob', needed, as Andrej pointed out.

And about the renaming: when I rewrote `init' and `dump' last time I
was tempted to make `dump' a function defined in `init' and call it
`compdump'. I.e.: yes I think we should rename them, maybe even add a
`#!/.../zsh' in front and write a comment that they may be used as
shell scripts. Especially since `dump' may now be called any time.

Bye
 Sven

diff -u of/Completion/init Functions/Completion/init
--- of/Completion/init	Tue Feb 23 13:18:40 1999
+++ Functions/Completion/init	Tue Feb 23 14:29:41 1999
@@ -58,23 +58,31 @@
 # name of the function containing the definition, the other arguments are the
 # command names for which this definition should be used.
 # With only one argument the function/variable-name _$1 is used.
+# If given the `-n' option, the function name is stored only if there wasn't
+# an older definition for the command.
 # If given the `-a' option, the function is defined as being autoloaded.
 
 defcomp() {
-  local name
+  local name autol new
 
+  if [[ "$1" = -n ]]; then
+    shift
+    new=yes
+  fi
   if [[ "$1" = -a ]]; then
     shift
     autol=yes
   fi
   if [[ $# -eq 1 ]]; then
-    comps[$1]="_$1"
-    [[ -z "$autol" ]] || autoload "_$1"
+    if [[ -z "$new" || "${+comps[$1]}" -eq 0 ]]; then
+      comps[$1]="_$1"
+      [[ -z "$autol" ]] || autoload "_$1"
+    fi
   else
     name="$1"
     shift
     for i; do
-      comps[$i]="$name"
+      [[ -z "$new" || "${+comps[$i]}" -eq 0 ]] && comps[$i]="$name"
     done
     [[ -z "$autol" ]] || autoload "$name"
   fi
@@ -177,7 +185,10 @@
   unset _i_line
 fi
 if [[ -z "$_i_done" ]]; then
-echo searching...
+  if [[ ! -o extendedglob ]]; then
+    _i_noextglob=yes
+    setopt extendedglob
+  fi
   for _i_dir in $fpath; do
     [[ $_i_dir = . ]] && continue
     for _i_file in $_i_dir/_*~*~(N); do
@@ -185,7 +196,7 @@
       _i_tag=$_i_line[1]
       shift _i_line
       if [[ $_i_tag = '#defcomp' ]]; then
-	defcomp -a ${_i_file:t} "${_i_line[@]}"
+	defcomp -n -a ${_i_file:t} "${_i_line[@]}"
       elif [[ $_i_tag = '#defpatcomp' ]]; then
 	defpatcomp -a "${_i_file:t}" "${_i_line[@]}"
       elif [[ $_i_tag = '#defkeycomp' ]]; then
@@ -211,9 +222,11 @@
       fi
     done
 
-  unset _i_dir _i_line _i_file _i_tag
+  [[ -z "$_i_noextglob" ]] || unsetopt extendedglob
+
+  unset _i_dir _i_line _i_file _i_tag _i_noextglob
 
-  # if autodumping was requested, do it now.
+  # If autodumping was requested, do it now.
 
   (( _i_autodump )) && builtin . ${_i_initname:h}/dump
 fi

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author