zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <pws@csr.com>
To: zsh-workers@sunsite.dk
Subject: Re: _canonical_path not working on *BSD
Date: Thu, 27 Mar 2008 11:25:06 +0000	[thread overview]
Message-ID: <20080327112506.7298e9ef@news01> (raw)
In-Reply-To: <20080327120807.415095ee@raveland.org>

On Thu, 27 Mar 2008 12:08:07 +0100
Pea <zsh@raveland.org> wrote:
> [pea@pea-dsktp:~]% umount _canonical_paths_get_canonical_path:unfunction:1: no such hash table element: chpwd
> _canonical_paths_get_canonical_path:unfunction:1: no such hash table element: chpwd

I thought unfunction was silent if a function didn't exist, as is now
true of (and required for) unset, but apparently not.

Since I can't seem to get away from this, I've rewritten the function
more canonically so that the helper functions only get loaded once
and aren't buried in the body of the main function that gets stored.
Most of the patch is consequent rearrangement.

Index: Completion/Unix/Type/_canonical_paths
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_canonical_paths,v
retrieving revision 1.3
diff -u -r1.3 _canonical_paths
--- Completion/Unix/Type/_canonical_paths	27 Mar 2008 10:35:21 -0000	1.3
+++ Completion/Unix/Type/_canonical_paths	27 Mar 2008 11:20:34 -0000
@@ -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 @@
   # 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 @@
   done
 }
 
-local base=$PREFIX
-typeset -i blimit
+_canonical_paths() {
+  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]}
 
-_canonical_paths_add_paths $base
+  local expl ret=1 tag=$1 desc=$2
 
-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+=/
+  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 "$@"

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


  reply	other threads:[~2008-03-27 11:25 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-26 10:44 Baptiste Daroussin
2008-03-26 15:01 ` Debian bugs (Re: _canonical_path not working on *BSD) Bart Schaefer
2008-03-26 15:25   ` Clint Adams
2008-03-26 15:05 ` _canonical_path not working on *BSD Peter Stephenson
2008-03-26 15:27   ` Baptiste Daroussin
2008-03-26 15:34     ` Peter Stephenson
2008-03-26 15:51       ` Pea
2008-03-26 15:59       ` Clint Adams
2008-03-26 15:21 ` Pea
2008-03-26 15:36 ` Bart Schaefer
2008-03-26 15:40   ` Peter Stephenson
2008-03-26 16:04     ` Peter Stephenson
2008-03-26 16:18       ` Bart Schaefer
2008-03-26 16:21       ` Peter Stephenson
2008-03-26 16:38         ` Pea
2008-03-26 16:46           ` Peter Stephenson
2008-03-26 17:08             ` Pea
2008-03-26 17:17             ` Baptiste Daroussin
2008-03-27 10:23             ` Peter Stephenson
2008-03-27 11:08               ` Pea
2008-03-27 11:25                 ` Peter Stephenson [this message]
2008-03-27 12:15                   ` PATCH: cd -q (was Re: _canonical_path ...) Peter Stephenson
2008-03-27 12:25                     ` Stephane Chazelas
2008-03-27 12:35                     ` Mikael Magnusson
2008-03-27 12:48                       ` Peter Stephenson
2008-03-27 12:56                         ` Mikael Magnusson
2008-03-27 18:45                     ` Peter Stephenson
2008-03-28  8:16                       ` Pea
2008-03-28 11:01                       ` Mikael Magnusson
2008-03-28 14:35                         ` Peter Stephenson
2008-03-27 12:31                   ` _canonical_path not working on *BSD Pea
2008-03-27 15:39               ` Bart Schaefer
2008-03-27 18:06                 ` Peter Stephenson
2008-03-28  1:01                   ` Bart Schaefer
2008-03-28  7:51                     ` Mikael Magnusson
2008-03-28 10:01                     ` Peter Stephenson
2008-03-26 16:25       ` Pea

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=20080327112506.7298e9ef@news01 \
    --to=pws@csr.com \
    --cc=zsh-workers@sunsite.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).