1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-01-01 05:16:05 +01:00

38866: update add-zle-hook-widget doc for 38850, bug fixes

Edge case handling, wrap in anonymous function for kshautoload management.
This commit is contained in:
Barton E. Schaefer 2016-07-17 12:04:48 -07:00
parent 18d676ff19
commit e3884c60ed
3 changed files with 51 additions and 32 deletions

View file

@ -1,3 +1,11 @@
2016-07-17 Barton E. Schaefer <schaefer@zsh.org>
* 38866: Doc/Zsh/contrib.yo: update add-zle-hook-widget for 38850.
* 38866 (+ tweak 38872): Functions/Zle/add-zle-hook-widget: fix
edge case handling, wrap in anonymous function for kshautoload
management.
2016-07-17 Daniel Shahaf <d.s@daniel.shahaf.name>
* users/21752: Doc/Zsh/mod_zleparameter.yo: Extend

View file

@ -340,23 +340,20 @@ those additional widgets.
var(hook) is one of tt(isearch-exit), tt(isearch-update),
tt(line-pre-redraw), tt(line-init), tt(line-finish), tt(history-line-set),
or tt(keymap-select), corresponding to each of the special widgets
tt(zle-isearch-exit), etc.
tt(zle-isearch-exit), etc. The special widget names are also accepted
as the var(hook) argument.
var(widgetname) is the name of a ZLE widget. If no options are given this
is added to the array of widgets to be invoked in the given hook context.
Note that the hooks are called as widgets, that is, with
example(tt(zle )var(widgetname)tt( -Nw "$@"))
rather than as a function call.
In typical usage, var(widgetname) has the form var(index)tt(:)var(name).
In this case var(index) is an integer which determines the order in which
the widget var(name) will be called relative to other widgets in the
array. Widgets having the same var(index) are called in unspecified
order. However, var(widgetname) may omit the index, in which case an
index is computed for it to arrange for it to be called in the order
in which it was added to the array.
vindex(WIDGET, in hooks)
Note that this means that the `tt(WIDGET)' special parameter tracks the
var(widgetname) when the widget function is called, rather than tracking
the name of the corresponding special hook widget.
If the option tt(-d) is given, the var(widgename) is removed from
If the option tt(-d) is given, the var(widgetname) is removed from
the array of widgets to be executed.
If the option tt(-D) is given, the var(widgetname) is treated as a pattern
@ -370,7 +367,6 @@ passed as arguments to tt(autoload) as with tt(add-zsh-hook). The
widget is also created with `tt(zle -N )var(widgetname)' to cause the
corresponding function to be loaded the first time the hook is called.
The arrays of var(widgetname) are currently maintained in tt(zstyle)
contexts, one for each var(hook) context, with a style of `tt(widgets)'.
If the tt(-L) option is given, this set of styles is listed with

View file

@ -18,6 +18,8 @@
#
# The -L option lists the hooks and their associated widgets.
() { # Preserve caller global option settings
emulate -L zsh
# This is probably more safeguarding than necessary
@ -35,25 +37,23 @@ local -a hooktypes=( zle-isearch-exit zle-isearch-update
# Stash in zstyle to make it global
zstyle zle-hook types ${hooktypes#zle-}
for hook in $hooktypes
do
function azhw:$hook {
local -a hook_widgets
local hook
# Values of these styles look like number:name
# and we run them in number order
zstyle -a $WIDGET widgets hook_widgets
for hook in "${(@)${(@on)hook_widgets[@]}#<->:}"; do
if [[ "$hook" = user:* ]]; then
# Preserve $WIDGET within the renamed widget
zle "$hook" -N "$@"
else
zle "$hook" -Nw "$@"
fi || return
done
return 0
}
done
# Relying on multifuncdef option here
function azhw:${^hooktypes} {
local -a hook_widgets
local hook
# Values of these styles look like number:name
# and we run them in number order
zstyle -a $WIDGET widgets hook_widgets
for hook in "${(@)${(@on)hook_widgets[@]}#<->:}"; do
if [[ "$hook" = user:* ]]; then
# Preserve $WIDGET within the renamed widget
zle "$hook" -N "$@"
else
zle "$hook" -Nw "$@"
fi || return
done
return 0
}
# Redefine ourself with the setup left out
@ -127,12 +127,25 @@ function add-zle-hook-widget {
fi
fi
else
# Check whether attempting to add a widget named for the hook
if [[ "$fn" = "$hook" ]]; then
if [[ -n "${widgets[$fn]}" ]]; then
print -u2 "Cannot hook $fn to itself"
return 1
fi
# No point in building the array until another is added
autoload "${autoopts[@]}" -- "$fn"
zle -N "$fn"
return 0
fi
integer i=${#options[ksharrays]}-2
zstyle -g extant_hooks "$hook" widgets
# Check for an existing widget, add it as the first hook
if [[ ${widgets[$hook]} != "user:azhw:$hook" ]]; then
zle -A "$hook" "${widgets[$hook]}"
extant_hooks=(0:"${widgets[$hook]}" "${extant_hooks[@]}")
if [[ -n ${widgets[$hook]} ]]; then
zle -A "$hook" "${widgets[$hook]}"
extant_hooks=(0:"${widgets[$hook]}" "${extant_hooks[@]}")
fi
zle -N "$hook" azhw:"$hook"
fi
# Add new widget only if not already in the hook list
@ -155,6 +168,8 @@ function add-zle-hook-widget {
fi
}
} "$@" # Resume caller global options
# Handle zsh autoloading conventions:
# - "file" appears last in zsh_eval_context when "source"-ing
# - "evalautofunc" appears with kshautoload set or autoload -k