diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Completion/Unix/Type/_canonical_paths | 129 |
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 "$@" |