mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-28 05:00:59 +01: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
|
|
@ -1,3 +1,9 @@
|
||||||
|
2016-06-12 Barton E. Schaefer <schaefer@zsh.org>
|
||||||
|
|
||||||
|
* 38670: Doc/Zsh/contrib.yo, Functions/Zle/add-zle-hook-widget:
|
||||||
|
New function for managing ZLE special widgets, modeled after
|
||||||
|
Functions/Misc/add-zsh-hook.
|
||||||
|
|
||||||
2016-06-09 Oliver Kiddle <opk@zsh.org>
|
2016-06-09 Oliver Kiddle <opk@zsh.org>
|
||||||
|
|
||||||
* 38579: Functions/Zle/bracketed-paste-magic: simplify saving
|
* 38579: Functions/Zle/bracketed-paste-magic: simplify saving
|
||||||
|
|
|
||||||
|
|
@ -292,11 +292,11 @@ cindex(hook function utility)
|
||||||
|
|
||||||
startitem()
|
startitem()
|
||||||
findex(add-zsh-hook)
|
findex(add-zsh-hook)
|
||||||
item(tt(add-zsh-hook) [ tt(-dD) ] [ tt(-Uzk) ] var(hook) var(function))(
|
item(tt(add-zsh-hook) [ tt(-L) | tt(-dD) ] [ tt(-Uzk) ] var(hook) var(function))(
|
||||||
Several functions are special to the shell, as described in the section
|
Several functions are special to the shell, as described in the section
|
||||||
ifnzman(Special Functions, noderef(Functions))\
|
ifnzman(Special Functions, noderef(Functions))\
|
||||||
ifzman(SPECIAL FUNCTIONS, see zmanref(zshmisc)),
|
ifzman(SPECIAL FUNCTIONS, see zmanref(zshmisc)),
|
||||||
in that they are automatic called at a specific point during shell execution.
|
in that they are automatically called at specific points during shell execution.
|
||||||
Each has an associated array consisting of names of functions to be
|
Each has an associated array consisting of names of functions to be
|
||||||
called at the same point; these are so-called `hook functions'.
|
called at the same point; these are so-called `hook functions'.
|
||||||
The shell function tt(add-zsh-hook) provides a simple way of adding or
|
The shell function tt(add-zsh-hook) provides a simple way of adding or
|
||||||
|
|
@ -312,6 +312,9 @@ var(function) is name of an ordinary shell function. If no options
|
||||||
are given this will be added to the array of functions to be executed
|
are given this will be added to the array of functions to be executed
|
||||||
in the given context.
|
in the given context.
|
||||||
|
|
||||||
|
If the option tt(-L) is given, the current values for the hook arrays
|
||||||
|
are listed with tt(typeset).
|
||||||
|
|
||||||
If the option tt(-d) is given, the var(function) is removed from
|
If the option tt(-d) is given, the var(function) is removed from
|
||||||
the array of functions to be executed.
|
the array of functions to be executed.
|
||||||
|
|
||||||
|
|
@ -323,6 +326,55 @@ The options tt(-U), tt(-z) and tt(-k) are passed as arguments to
|
||||||
tt(autoload) for var(function). For functions contributed with zsh, the
|
tt(autoload) for var(function). For functions contributed with zsh, the
|
||||||
options tt(-Uz) are appropriate.
|
options tt(-Uz) are appropriate.
|
||||||
)
|
)
|
||||||
|
findex(add-zle-hook-widget)
|
||||||
|
item(tt(add-zle-hook-widget) [ tt(-L) | tt(-dD) ] [ tt(-Uzk) ] var(hook) var(widgetname))(
|
||||||
|
Several widget names are special to the line editor, as described in the section
|
||||||
|
ifnzman(Special Widgets, noderef(Zle Widgets))\
|
||||||
|
ifzman(Special Widgets, see zmanref(zshzle)),
|
||||||
|
in that they are automatically called at specific points during editing.
|
||||||
|
Unlike function hooks, these do not use a predefined array of other names
|
||||||
|
to call at the same point; the shell function tt(add-zle-hook-widget)
|
||||||
|
maintains a similar array and arranges for the special widget to invoke
|
||||||
|
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.
|
||||||
|
|
||||||
|
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) -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.
|
||||||
|
|
||||||
|
If the option tt(-d) is given, the var(widgename) 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
|
||||||
|
and any matching names of widgets are removed from the array.
|
||||||
|
|
||||||
|
If var(widgetname) does not name an existing widget when added to the
|
||||||
|
array, it is assumed that a shell function also named var(widgetname) is
|
||||||
|
meant to provide the implementation of the widget. This name is therefore
|
||||||
|
marked for autoloading, and the options tt(-U), tt(-z) and tt(-k) are
|
||||||
|
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.
|
||||||
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
||||||
texinode(Recent Directories)(Other Directory Functions)(Utilities)(User Contributions)
|
texinode(Recent Directories)(Other Directory Functions)(Utilities)(User Contributions)
|
||||||
|
|
|
||||||
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