mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 05:16:05 +01:00
38715: add-zle-hook-widget: assorted ksharrays fixes; assign an index to any hook that is added without one, to preserve append ordering
This commit is contained in:
parent
25ae250068
commit
0b8ab3a21a
3 changed files with 69 additions and 36 deletions
|
@ -1,3 +1,9 @@
|
|||
2016-06-19 Barton E. Schaefer <schaefer@brasslantern.com>
|
||||
|
||||
* 38715: Doc/Zsh/contrib.yo, Functions/Zle/add-zle-hook-widget:
|
||||
assorted ksharrays fixes; assign an index to any hook that is
|
||||
added without one, to preserve append ordering
|
||||
|
||||
2016-06-18 Barton E. Schaefer <schaefer@zsh.org>
|
||||
|
||||
* unposted: Functions/Misc/zed: localoptions noksharrays
|
||||
|
|
|
@ -345,14 +345,16 @@ tt(zle-isearch-exit), etc.
|
|||
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
|
||||
`tt(zle )var(widgetname)tt( -Nw)' rather than as a function call.
|
||||
example(tt(zle )var(widgetname)tt( -Nw "$@"))
|
||||
rather than as a function call.
|
||||
|
||||
The arrays of var(widgetname) are maintained in several 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
|
||||
`tt(zstyle -L)'. These styles may be updated directly with tt(zstyle)
|
||||
commands, but the special widgets that refer to the styles are created
|
||||
only if tt(add-zle-hook-widget) is called to add at least one widget.
|
||||
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.
|
||||
|
||||
If the option tt(-d) is given, the var(widgename) is removed from
|
||||
the array of widgets to be executed.
|
||||
|
@ -368,12 +370,14 @@ 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.
|
||||
|
||||
In addition, var(widgetname) may be of 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, and all widgets declared with an index are called before any
|
||||
widgets that have no index.
|
||||
|
||||
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
|
||||
`tt(zstyle -L)'. This implementation may change, and the special widgets
|
||||
that refer to the styles are created only if tt(add-zle-hook-widget) is
|
||||
called to add at least one widget, so if this function is used for any
|
||||
hooks, then all hooks should be managed only via this function.
|
||||
)
|
||||
enditem()
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#
|
||||
# WIDGET may be of the form INDEX:NAME in which case the INDEX determines
|
||||
# the order in which the widget executes relative to other hook widgets.
|
||||
# Othewise the widget is assigned an index that appends it to the array.
|
||||
#
|
||||
# With -d, remove the widget from the hook instead; delete the hook
|
||||
# variable if it is empty.
|
||||
|
@ -17,38 +18,45 @@
|
|||
# same name is marked for autoload; -U is passed down to autoload if that
|
||||
# is given, as are -z and -k. (This is harmless if the function is
|
||||
# already defined.) The WIDGET is then created with zle -N.
|
||||
#
|
||||
# The -L option lists the hooks and their associated widgets.
|
||||
|
||||
emulate -L zsh
|
||||
|
||||
# Setup - create the base functions for hook widgets that call the others
|
||||
|
||||
zmodload zsh/parameter || {
|
||||
print -u2 "Need parameter module for zle hooks"
|
||||
# This is probably more safeguarding than necessary
|
||||
zmodload -e zsh/zle || return 1
|
||||
{ zmodload zsh/parameter && zmodload zsh/zleparameter } || {
|
||||
print -u2 "Need parameter modules for zle hooks"
|
||||
return 1
|
||||
}
|
||||
|
||||
local -a hooktypes=( isearch-exit isearch-update
|
||||
line-pre-redraw line-init line-finish
|
||||
history-line-set keymap-select )
|
||||
# Setup - create the base functions for hook widgets that call the others
|
||||
|
||||
local -a hooktypes=( zle-isearch-exit zle-isearch-update
|
||||
zle-line-pre-redraw zle-line-init zle-line-finish
|
||||
zle-history-line-set zle-keymap-select )
|
||||
# Stash in zstyle to make it global
|
||||
zstyle zle-hook types $hooktypes
|
||||
zstyle zle-hook types ${hooktypes#zle-}
|
||||
|
||||
for hook in $hooktypes
|
||||
do
|
||||
function zle-$hook {
|
||||
function azhw:$hook {
|
||||
local -a hook_widgets
|
||||
local hook
|
||||
# Values of these styles look like number:name
|
||||
# and we run them in number order
|
||||
# $funcstack is more reliable than $0
|
||||
# Also, ksh_arrays is annoying
|
||||
emulate zsh -c 'zstyle -a $funcstack[2] widgets hook_widgets'
|
||||
for hook in "${@${(@on)hook_widgets}#*:}"
|
||||
do
|
||||
zle "$hook" -Nw || return
|
||||
zstyle -a $WIDGET widgets hook_widgets
|
||||
for hook in "${(@)${(@on)hook_widgets[@]}#<->:}"; do
|
||||
zle "$hook" -Nw "$@" || return
|
||||
done
|
||||
return 0
|
||||
}
|
||||
# Check for an existing widget, add it as the first hook
|
||||
if [[ ${widgets[$hook]} = user:* ]]; then
|
||||
zle -A "$hook" "${widgets[$hook]}"
|
||||
zstyle -- "$hook" widgets 0:"${widgets[$hook]}"
|
||||
zle -N "$hook" azhw:"$hook"
|
||||
fi
|
||||
done
|
||||
|
||||
# Redefine ourself with the setup left out
|
||||
|
@ -93,25 +101,27 @@ function add-zle-hook-widget {
|
|||
done
|
||||
shift $(( OPTIND - 1 ))
|
||||
|
||||
1=${1#zle-} # Strip prefix not stored in zle-hook types style
|
||||
|
||||
if (( list )); then
|
||||
zstyle -L "zle-(${1:-${(@j:|:)hooktypes}})" widgets
|
||||
zstyle -L "zle-(${1:-${(@j:|:)hooktypes[@]}})" widgets
|
||||
return $?
|
||||
elif (( help || $# != 2 || ${hooktypes[(I)${1#zle-}]} == 0 )); then
|
||||
elif (( help || $# != 2 || ${hooktypes[(I)$1]} == 0 )); then
|
||||
print -u$(( 2 - help )) $usage
|
||||
return $(( 1 - help ))
|
||||
fi
|
||||
|
||||
local -aU extant_hooks
|
||||
local hook="zle-${1#zle-}"
|
||||
local hook="zle-$1"
|
||||
local fn="$2"
|
||||
|
||||
if (( del )); then
|
||||
# delete, if hook is set
|
||||
if zstyle -g extant_hooks "$hook" widgets; then
|
||||
if (( del == 2 )); then
|
||||
set -A extant_hooks ${extant_hooks:#(<->:|)${~fn}}
|
||||
set -A extant_hooks ${extant_hooks[@]:#(<->:|)${~fn}}
|
||||
else
|
||||
set -A extant_hooks ${extant_hooks:#(<->:|)$fn}
|
||||
set -A extant_hooks ${extant_hooks[@]:#(<->:|)$fn}
|
||||
fi
|
||||
# unset if no remaining entries
|
||||
if (( ${#extant_hooks} )); then
|
||||
|
@ -121,15 +131,28 @@ function add-zle-hook-widget {
|
|||
fi
|
||||
fi
|
||||
else
|
||||
integer i=${#options[ksharrays]}-2
|
||||
zstyle -g extant_hooks "$hook" widgets
|
||||
extant_hooks+=("$fn")
|
||||
if [[ "$fn" != <->:* ]]; then
|
||||
if [[ -z ${(M)extant_hooks[@]:#(<->:|)$fn} ]]; then
|
||||
# no index and not already hooked
|
||||
# assign largest existing index plus 10
|
||||
i=${${(On@)${(@M)extant_hooks[@]#<->:}%:}[i]}+10
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
i=${${(M)fn#<->:}%:}
|
||||
fn=${fn#<->:}
|
||||
fi
|
||||
extant_hooks+=("${i}:${fn}")
|
||||
zstyle -- "$hook" widgets "${extant_hooks[@]}"
|
||||
if [[ -z "${widgets[$fn]}" ]]; then
|
||||
autoload "${autoopts[@]}" -- "$fn"
|
||||
zle -N "$fn"
|
||||
zle -N -- "$fn"
|
||||
fi
|
||||
if [[ -z "${widgets[$hook]}" ]]; then
|
||||
zle -N "$hook"
|
||||
zle -N "$hook" azhw:"$hook"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue