about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Completion/Unix/Type/_canonical_paths129
2 files changed, 72 insertions, 61 deletions
diff --git a/ChangeLog b/ChangeLog
index 4774932ce..40ab94286 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2008-03-27  Peter Stephenson  <pws@csr.com>
 
+	* 24759: Completion/Unix/Type/_canonical_paths: unfunction
+	is noisy if function wasn't set.  Also sanitize use of
+	helper functions.
+
 	* 24757: Completion/Unix/Type/_canonical_paths: use
 	CHASE_LINKS and pwd to canonicalize the directory path.
 
diff --git a/Completion/Unix/Type/_canonical_paths b/Completion/Unix/Type/_canonical_paths
index e4101dc47..3274145a8 100644
--- a/Completion/Unix/Type/_canonical_paths
+++ b/Completion/Unix/Type/_canonical_paths
@@ -13,27 +13,13 @@
 # case they are already so. `tag' and `desc' arguments are well, obvious :) In
 # addition, the options -M, -J, -V, -1, -2, -n, -F, -X are passed to compadd.
 
-local __index
-typeset -a __gopts __opts
-
-zparseopts -D -a __gopts M: J: V: 1 2 n F: X: A:=__opts N=__opts
-
-: ${1:=canonical-paths} ${2:=path}
-
-__index=$__opts[(I)-A]
-(( $__index )) && set -- $@ ${(P)__opts[__index+1]}
-
-local expl ret=1 tag=$1 desc=$2
-
-shift 2
-
-if ! zmodload -F zsh/stat b:zstat 2>/dev/null; then
-  _wanted "$tag" expl "$desc" compadd $__gopts $@ && ret=0
-  return ret
-fi
-
-typeset REPLY
-typeset -a matches files
+_canonical_paths_pwd() {
+  # Get the canonical directory name by changing to it.
+  # To be run in a subshell.
+  (( ${+functions[chpwd]} )) && unfunction chpwd
+  setopt CHASE_LINKS
+  cd $1 2>/dev/null && pwd
+}
 
 _canonical_paths_get_canonical_path() {
   typeset newfile dir
@@ -55,34 +41,20 @@ _canonical_paths_get_canonical_path() {
   # Canonicalise the directory path.  We may not be able to
   # do this if we can't read all components.
   if [[ -d $REPLY ]]; then
-    dir="$(unfunction chpwd
-           setopt CHASE_LINKS
-           cd $REPLY 2>/dev/null && pwd)"
+    dir="$(_canonical_paths_pwd $REPLY)"
     if [[ -n $dir ]]; then
       REPLY=$dir
     fi
   elif [[ $REPLY = */*[^/] && $REPLY != /[^/]# ]]; then
     # Don't try this if there's a trailing slash or we're in
     # the root directory.
-    dir="$(unfunction chpwd
-           setopt CHASE_LINKS
-           cd ${REPLY%/*} 2>/dev/null && pwd)"
+    dir="$(_canonical_paths_pwd ${REPLY%/*})"
     if [[ -n $dir ]]; then
       REPLY=$dir/${REPLY##*/}
     fi
   fi
 }
 
-
-if (( $__opts[(I)-N] )); then
-  files=($@)
-else
-  for __index in $@; do
-    _canonical_paths_get_canonical_path $__index
-    files+=($REPLY)
-  done
-fi
-
 _canonical_paths_add_paths () {
   local origpref=$1 expref rltrim curpref canpref subdir
   [[ $2 != add ]] && matches=()
@@ -104,35 +76,70 @@ _canonical_paths_add_paths () {
   done
 }
 
-local base=$PREFIX
-typeset -i blimit
+_canonical_paths() {
+  local __index
+  typeset -a __gopts __opts
 
-_canonical_paths_add_paths $base
+  zparseopts -D -a __gopts M: J: V: 1 2 n F: X: A:=__opts N=__opts
 
-if [[ -z $base ]]; then
-  _canonical_paths_add_paths / add
-elif [[ $base == ..(/.(|.))#(|/) ]]; then
+  : ${1:=canonical-paths} ${2:=path}
 
-  # This style controls how many parent directory links (..) to chase searching
-  # for possible completions. The default is 8. Note that this chasing is
-  # triggered only when the user enters atleast a .. and the path completed
-  # contains only . or .. components. A value of 0 turns off .. link chasing
-  # altogether.
+  __index=$__opts[(I)-A]
+  (( $__index )) && set -- $@ ${(P)__opts[__index+1]}
 
-  zstyle -s ":completion:${curcontext}:$tag" \
-    canonical-paths-back-limit blimit || blimit=8
+  local expl ret=1 tag=$1 desc=$2
 
-  if [[ $base != */ ]]; then
-    [[ $base != *.. ]] && base+=.
-    base+=/
+  shift 2
+
+  if ! zmodload -F zsh/stat b:zstat 2>/dev/null; then
+    _wanted "$tag" expl "$desc" compadd $__gopts $@ && ret=0
+    return ret
   fi
-  until [[ $base.. -ef $base || blimit -le 0 ]]; do
-    base+=../
-    _canonical_paths_add_paths $base add
-    blimit+=-1
-  done
-fi
 
-_wanted "$tag" expl "$desc" compadd $__gopts -Q -U -a matches && ret=0
+  typeset REPLY
+  typeset -a matches files
+
+  if (( $__opts[(I)-N] )); then
+    files=($@)
+  else
+    for __index in $@; do
+      _canonical_paths_get_canonical_path $__index
+      files+=($REPLY)
+    done
+  fi
+
+  local base=$PREFIX
+  typeset -i blimit
+
+  _canonical_paths_add_paths $base
+
+  if [[ -z $base ]]; then
+    _canonical_paths_add_paths / add
+  elif [[ $base == ..(/.(|.))#(|/) ]]; then
+
+    # This style controls how many parent directory links (..) to chase searching
+    # for possible completions. The default is 8. Note that this chasing is
+    # triggered only when the user enters atleast a .. and the path completed
+    # contains only . or .. components. A value of 0 turns off .. link chasing
+    # altogether.
+
+    zstyle -s ":completion:${curcontext}:$tag" \
+      canonical-paths-back-limit blimit || blimit=8
+
+    if [[ $base != */ ]]; then
+      [[ $base != *.. ]] && base+=.
+      base+=/
+    fi
+    until [[ $base.. -ef $base || blimit -le 0 ]]; do
+      base+=../
+      _canonical_paths_add_paths $base add
+      blimit+=-1
+    done
+  fi
+
+  _wanted "$tag" expl "$desc" compadd $__gopts -Q -U -a matches && ret=0
+
+  return ret
+}
 
-return ret
+_canonical_paths "$@"