mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-23 04:30:24 +02:00
38670: New function for managing ZLE special widgets, modeled after Functions/Misc/add-zsh-hook.
This commit is contained in:
parent
20948d0889
commit
8e2ec4517f
3 changed files with 200 additions and 2 deletions
140
Functions/Zle/add-zle-hook-widget
Normal file
140
Functions/Zle/add-zle-hook-widget
Normal file
|
@ -0,0 +1,140 @@
|
|||
# Add to HOOK the given WIDGET
|
||||
#
|
||||
# HOOK is one of isearch-exit, isearch-update, line-pre-redraw, line-init,
|
||||
# line-finish, history-line-set, keymap-select (the zle- prefix is not
|
||||
# required).
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# With -d, remove the widget from the hook instead; delete the hook
|
||||
# variable if it is empty.
|
||||
#
|
||||
# -D behaves like -d, but pattern characters are active in the
|
||||
# widget name, so any matching widget will be deleted from the hook.
|
||||
#
|
||||
# Without -d, if the WIDGET is not already defined, a function having the
|
||||
# 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.
|
||||
|
||||
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"
|
||||
return 1
|
||||
}
|
||||
|
||||
local -a hooktypes=( isearch-exit isearch-update
|
||||
line-pre-redraw line-init line-finish
|
||||
history-line-set keymap-select )
|
||||
# Stash in zstyle to make it global
|
||||
zstyle zle-hook types $hooktypes
|
||||
|
||||
for hook in $hooktypes
|
||||
do
|
||||
function zle-$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
|
||||
done
|
||||
return 0
|
||||
}
|
||||
done
|
||||
|
||||
# Redefine ourself with the setup left out
|
||||
|
||||
function add-zle-hook-widget {
|
||||
local -a hooktypes
|
||||
zstyle -a zle-hook types hooktypes
|
||||
|
||||
# This part copied from add-zsh-hook
|
||||
local usage="Usage: $0 hook widgetname\nValid hooks are:\n $hooktypes"
|
||||
|
||||
local opt
|
||||
local -a autoopts
|
||||
integer del list help
|
||||
|
||||
while getopts "dDhLUzk" opt; do
|
||||
case $opt in
|
||||
(d)
|
||||
del=1
|
||||
;;
|
||||
|
||||
(D)
|
||||
del=2
|
||||
;;
|
||||
|
||||
(h)
|
||||
help=1
|
||||
;;
|
||||
|
||||
(L)
|
||||
list=1
|
||||
;;
|
||||
|
||||
([Uzk])
|
||||
autoopts+=(-$opt)
|
||||
;;
|
||||
|
||||
(*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $(( OPTIND - 1 ))
|
||||
|
||||
if (( list )); then
|
||||
zstyle -L "zle-(${1:-${(@j:|:)hooktypes}})" widgets
|
||||
return $?
|
||||
elif (( help || $# != 2 || ${hooktypes[(I)${1#zle-}]} == 0 )); then
|
||||
print -u$(( 2 - help )) $usage
|
||||
return $(( 1 - help ))
|
||||
fi
|
||||
|
||||
local -aU extant_hooks
|
||||
local hook="zle-${1#zle-}"
|
||||
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}}
|
||||
else
|
||||
set -A extant_hooks ${extant_hooks:#(<->:|)$fn}
|
||||
fi
|
||||
# unset if no remaining entries
|
||||
if (( ${#extant_hooks} )); then
|
||||
zstyle "$hook" widgets "${extant_hooks[@]}"
|
||||
else
|
||||
zstyle -d "$hook" widgets
|
||||
fi
|
||||
fi
|
||||
else
|
||||
zstyle -g extant_hooks "$hook" widgets
|
||||
extant_hooks+=("$fn")
|
||||
zstyle -- "$hook" widgets "${extant_hooks[@]}"
|
||||
if [[ -z "${widgets[$fn]}" ]]; then
|
||||
autoload "${autoopts[@]}" -- "$fn"
|
||||
zle -N "$fn"
|
||||
fi
|
||||
if [[ -z "${widgets[$hook]}" ]]; then
|
||||
zle -N "$hook"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle zsh autoloading conventions
|
||||
if [[ "$zsh_eval_context" = *loadautofunc && ! -o kshautoload ]]; then
|
||||
add-zle-hook-widget "$@"
|
||||
fi
|
Loading…
Add table
Add a link
Reference in a new issue