diff options
Diffstat (limited to 'Completion/Base')
-rw-r--r-- | Completion/Base/Completer/_approximate | 48 | ||||
-rw-r--r-- | Completion/Base/Completer/_prefix | 9 | ||||
-rw-r--r-- | Completion/Base/Core/_main_complete | 22 | ||||
-rw-r--r-- | Completion/Base/Utility/_numbers | 2 | ||||
-rw-r--r-- | Completion/Base/Utility/_shadow | 97 | ||||
-rw-r--r-- | Completion/Base/Utility/_values | 2 | ||||
-rw-r--r-- | Completion/Base/Widget/_complete_debug | 2 | ||||
-rw-r--r-- | Completion/Base/Widget/_complete_help | 3 |
8 files changed, 135 insertions, 50 deletions
diff --git a/Completion/Base/Completer/_approximate b/Completion/Base/Completer/_approximate index dcd8b2776..96860b5a7 100644 --- a/Completion/Base/Completer/_approximate +++ b/Completion/Base/Completer/_approximate @@ -12,7 +12,6 @@ local _comp_correct _correct_expl _correct_group comax cfgacc match local oldcontext="${curcontext}" opm="$compstate[pattern_match]" -local dounfunction integer ret=1 if [[ "$1" = -a* ]]; then @@ -44,34 +43,31 @@ fi _tags corrections original -# Otherwise temporarily define a function to use instead of -# the builtin that adds matches. This is used to be able -# to stick the `(#a...)' in the right place (after an -# ignored prefix). +# Otherwise temporarily define a function to use instead of the builtin that +# adds matches. This is used to be able to stick the `(#a...)' in the right +# place (after an ignored prefix). # -# Current shell structure for use with "always", to make sure -# we unfunction the compadd. +# Current shell structure for use with "always", to make sure we unfunction our +# compadd and restore any compadd function defined previously. { -if (( ! $+functions[compadd] )); then - dounfunction=1 - compadd() { - local ppre="$argv[(I)-p]" - - [[ ${argv[(I)-[a-zA-Z]#U[a-zA-Z]#]} -eq 0 && - "${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return - - if [[ "$PREFIX" = \~* && ( ppre -eq 0 || "$argv[ppre+1]" != \~* ) ]]; then - PREFIX="~(#a${_comp_correct})${PREFIX[2,-1]}" - else - PREFIX="(#a${_comp_correct})$PREFIX" - fi +_shadow -s _approximate compadd +compadd() { + local ppre="$argv[(I)-p]" - (( $_correct_group && ${${argv[1,(r)-(|-)]}[(I)-*[JV]]} )) && - _correct_expl[_correct_group]=${argv[1,(r)-(-|)][(R)-*[JV]]} + [[ ${argv[(I)-[a-zA-Z]#U[a-zA-Z]#]} -eq 0 && + "${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return - builtin compadd "$_correct_expl[@]" "$@" - } -fi + if [[ "$PREFIX" = \~* && ( ppre -eq 0 || "$argv[ppre+1]" != \~* ) ]]; then + PREFIX="~(#a${_comp_correct})${PREFIX[2,-1]}" + else + PREFIX="(#a${_comp_correct})$PREFIX" + fi + + (( $_correct_group && ${${argv[1,(r)-(|-)]}[(I)-*[JV]]} )) && + _correct_expl[_correct_group]=${argv[1,(r)-(-|)][(R)-*[JV]]} + + compadd@_approximate "$_correct_expl[@]" "$@" +} _comp_correct=1 @@ -115,7 +111,7 @@ while [[ _comp_correct -le comax ]]; do done } always { - [[ -n $dounfunction ]] && (( $+functions[compadd] )) && unfunction compadd + _unshadow } (( ret == 0 )) && return 0 diff --git a/Completion/Base/Completer/_prefix b/Completion/Base/Completer/_prefix index 74be5f47d..aea2f7863 100644 --- a/Completion/Base/Completer/_prefix +++ b/Completion/Base/Completer/_prefix @@ -49,13 +49,8 @@ for tmp in "$comp[@]"; do fi if [[ "$tmp" != _prefix ]] && "$tmp"; then - [[ compstate[nmatches] -gt 1 ]] && return 0 - compadd -U -i "$IPREFIX" -I "$ISUFFIX" - "${compstate[unambiguous]%$suf}x" - compstate[list]= - if [[ -n $compstate[unambiguous] ]]; then - compstate[insert]=unambiguous - else - compstate[insert]=0 + if [[ -n $compstate[old_list] || ${compstate[unambiguous]%$suf} == $PREFIX ]]; then + compstate[to_end]=match fi return 0 fi diff --git a/Completion/Base/Core/_main_complete b/Completion/Base/Core/_main_complete index 169ca1f40..408a66ee3 100644 --- a/Completion/Base/Core/_main_complete +++ b/Completion/Base/Core/_main_complete @@ -93,19 +93,15 @@ fi if [[ -z "$compstate[quote]" ]]; then if [[ -o equals ]] && compset -P 1 '='; then compstate[context]=equal - elif [[ "$PREFIX" != */* && "$PREFIX[1]" = '~' ]]; then - if [[ "$PREFIX" = '~['[^\]]# ]]; then - # Inside ~[...] should be treated as a subscript. - compset -p 2 - # To be consistent, we ignore all but the contents of the square - # brackets. - compset -S '\]*' - compstate[context]=subscript - [[ -n $_comps[-subscript-] ]] && $_comps[-subscript-] && return - else - compset -p 1 - compstate[context]=tilde - fi + elif [[ "$PREFIX" = \~\[[^]]# ]]; then + # Inside ~[...] should be treated as a subscript. + compset -p 2 + # To be consistent, we ignore all but the contents of the square brackets. + compset -S '\]*' + compstate[context]=subscript + elif [[ "$PREFIX" = \~[^/]# ]]; then + compset -p 1 + compstate[context]=tilde fi fi diff --git a/Completion/Base/Utility/_numbers b/Completion/Base/Utility/_numbers index 97bb8b4c8..069fc75a4 100644 --- a/Completion/Base/Utility/_numbers +++ b/Completion/Base/Utility/_numbers @@ -73,7 +73,7 @@ elif [[ -prefix $~pat || $PREFIX = $~partial ]]; then zformat -f suffix "$suffixfmt" "x:${${argv[i+1]#:}%%:*}" \ "X:${${argv[i+1]#:}#*:}" "d:${#${argv[i+1]}[1]#:}" \ i:i r:$(( $# - i - 1)) - suffixes+="$suffix" + suffixes+="${suffix//\%/%%}" done [[ -n $suffixes ]] && formats+=( x:$suffixes ) diff --git a/Completion/Base/Utility/_shadow b/Completion/Base/Utility/_shadow new file mode 100644 index 000000000..9e78af38f --- /dev/null +++ b/Completion/Base/Utility/_shadow @@ -0,0 +1,97 @@ +#autoload + +## Recommended usage: +# { +# _shadow fname +# function fname { +# # Do your new thing +# } +# # Invoke callers of fname +# } always { +# _unshadow +# } +## Alternate usage: +# { +# _shadow -s suffix fname +# function fname { +# # Do other stuff +# fname@suffix new args for fname +# } +# # Invoke callers of fname +# } always { +# _unshadow +# } +## + +# BUGS: +# * `functions -c` acts like `autoload +X` +# * name collisions are possible in alternate usage +# * functions that examine $0 probably misfire + +zmodload zsh/parameter # Or what? + +# This probably never comes up, but protect ourself from recursive call +# chains that may duplicate the top elements of $funcstack by creating +# a counter of _shadow calls and using it to make shadow names unique. +builtin typeset -gHi .shadow.depth=0 +builtin typeset -gHa .shadow.stack + +# Create a copy of each fname so that a caller may redefine +_shadow() { + emulate -L zsh + local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:$((.shadow.depth+1)) ) + local fname shadowname + local -a fnames + zparseopts -K -A fsfx -D s: + for fname; do + shadowname=${fname}@${fsfx[-s]} + if (( ${+functions[$shadowname]} )) + then + # Called again with the same -s, just ignore it + continue + elif (( ${+functions[$fname]} )) + then + builtin functions -c -- $fname $shadowname + fnames+=(f@$fname) + elif (( ${+builtins[$fname]} )) + then + eval "function -- ${(q-)shadowname} { builtin ${(q-)fname} \"\$@\" }" + fnames+=(b@$fname) + else + eval "function -- ${(q-)shadowname} { command ${(q-)fname} \"\$@\" }" + fnames+=(c@$fname) + fi + done + [[ -z $REPLY ]] && REPLY=${fsfx[-s]} + builtin set -A .shadow.stack ${fsfx[-s]} $fnames -- ${.shadow.stack} + ((.shadow.depth++)) +} + +# Remove the redefined function and shadowing name +_unshadow() { + emulate -L zsh + local fname shadowname fsfx=${.shadow.stack[1]} + local -a fnames + [[ -n $fsfx ]] || return 1 + shift .shadow.stack + while [[ ${.shadow.stack[1]?no shadows} != -- ]]; do + fname=${.shadow.stack[1]#?@} + shadowname=${fname}@${fsfx} + if (( ${+functions[$fname]} )); then + builtin unfunction -- $fname + fi + case ${.shadow.stack[1]} in + (f@*) builtin functions -c -- $shadowname $fname ;& + ([bc]@*) builtin unfunction -- $shadowname ;; + esac + shift .shadow.stack + done + [[ -z $REPLY ]] && REPLY=$fsfx + shift .shadow.stack + ((.shadow.depth--)) +} + +# This is tricky. When we call _shadow recursively from autoload, +# there's an extra level of stack in $functrace that will confuse +# the later call to _unshadow. Fool ourself into working correctly. +(( ARGC )) && _shadow -s ${funcstack[2]}:${functrace[2]}:1 "$@" diff --git a/Completion/Base/Utility/_values b/Completion/Base/Utility/_values index 688ada848..5ed79e890 100644 --- a/Completion/Base/Utility/_values +++ b/Completion/Base/Utility/_values @@ -60,7 +60,7 @@ if compvalues -i "$keep[@]" "$@"; then _describe "$descr" \ noargs "$sep[@]" -M 'r:|[_-]=* r:|=*' -- \ args -S "${argsep}" -M 'r:|[_-]=* r:|=*' -- \ - opts -qS "${argsep}" -r "${argsep}${sep} \\t\\n\\-" -M 'r:|[_-]=* r:|=*' + opts -qS "${argsep}" -r "${argsep}${sep[2]} \\t\\n\\-" -M 'r:|[_-]=* r:|=*' curcontext="$oldcontext" diff --git a/Completion/Base/Widget/_complete_debug b/Completion/Base/Widget/_complete_debug index 94fd4accd..d8b1bd837 100644 --- a/Completion/Base/Widget/_complete_debug +++ b/Completion/Base/Widget/_complete_debug @@ -19,7 +19,7 @@ integer debug_fd=-1 setopt localoptions no_ignorebraces debug_indent=( '%'{3..20}'(e. .)' ) } - local PROMPT4 PS4="${(j::)debug_indent}+%N:%i> " + local PROMPT4="$PROMPT4" PS4="${(j::)debug_indent}+%N:%i> " setopt xtrace : $ZSH_NAME $ZSH_VERSION ${1:-_main_complete} diff --git a/Completion/Base/Widget/_complete_help b/Completion/Base/Widget/_complete_help index 69855de9d..da5947e7f 100644 --- a/Completion/Base/Widget/_complete_help +++ b/Completion/Base/Widget/_complete_help @@ -10,6 +10,7 @@ _complete_help() { local -H _help_filter_funcstack="alternative|call_function|describe|dispatch|wanted|requested|all_labels|next_label" { + _shadow compadd compcall zstyle compadd() { return 1 } compcall() { _help_sort_tags use-compctl } zstyle() { @@ -43,7 +44,7 @@ _complete_help() { ${1:-_main_complete} } always { - unfunction compadd compcall zstyle + _unshadow compadd compcall zstyle } for i in "${(@ok)help_funcs}"; do |