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

Re: _canonical_path not working on *BSD



Le Thu, 27 Mar 2008 11:25:06 +0000,
Peter Stephenson <pws@xxxxxxx> a écrit :

> On Thu, 27 Mar 2008 12:08:07 +0100
> Pea <zsh@xxxxxxxxxxxx> 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 "$@"
> 

This works fine on OpenBSD.

Regards,

-- 
Pierre-Emmanuel André <pea at raveland.org>
GPG key: 0x7AE329DC



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