mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-17 22:31:12 +01:00
72 lines
1.9 KiB
Text
72 lines
1.9 KiB
Text
|
#autoload
|
||
|
|
||
|
## Recommended usage:
|
||
|
# {
|
||
|
# _shadow fname
|
||
|
# function fname {
|
||
|
# # Do your new thing
|
||
|
# }
|
||
|
# # Invoke callers of fname
|
||
|
# } always {
|
||
|
# _unshadow fname
|
||
|
# }
|
||
|
## Alternate usage:
|
||
|
# {
|
||
|
# _shadow -s suffix fname
|
||
|
# function fname {
|
||
|
# # Do other stuff
|
||
|
# fname@suffix new args for fname
|
||
|
# }
|
||
|
# # Invoke callers of fname
|
||
|
# } always {
|
||
|
# _unshadow -s suffix fname
|
||
|
# }
|
||
|
##
|
||
|
|
||
|
# 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.
|
||
|
typeset -gHi _shadowdepth=0
|
||
|
|
||
|
# Create a copy of each fname so that a caller may redefine
|
||
|
_shadow() {
|
||
|
local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:$((_shadowdepth+1)) )
|
||
|
local fname
|
||
|
zparseopts -K -A fsfx -D s:
|
||
|
for fname; do
|
||
|
local shadowname=${fname}@${fsfx[-s]}
|
||
|
(( ${+functions[$fname]} )) &&
|
||
|
builtin functions -c $fname $shadowname
|
||
|
done
|
||
|
((_shadowdepth++))
|
||
|
}
|
||
|
|
||
|
# Remove the redefined function and shadowing name
|
||
|
_unshadow() {
|
||
|
local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:${_shadowdepth} )
|
||
|
local fname
|
||
|
zparseopts -K -A fsfx -D s:
|
||
|
for fname; do
|
||
|
local shadowname=${fname}@${fsfx[-s]}
|
||
|
if (( ${+functions[$shadowname]} )); then
|
||
|
builtin functions -c $shadowname $fname
|
||
|
builtin unfunction $shadowname
|
||
|
elif (( ${+functions[$fname]} )); then
|
||
|
builtin unfunction $fname
|
||
|
fi
|
||
|
done
|
||
|
((_shadowdepth--))
|
||
|
}
|
||
|
|
||
|
# 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 "$@"
|