driver: Make it reentrant.

This fixes an infinite recursion in zsh without zle-line-pre-redraw [≤5.2] in
the following situation:

% source zsh-syntax-highlighting.zsh
% eval "my-self-insert() { zle -M 'foobar'; ${(q)widgets[self-insert]#*:} \"\$@\" }"
% zle -N self-insert my-self-insert
% source zsh-syntax-highlighting.zsh

Fixes #305.
This commit is contained in:
Daniel Shahaf 2016-08-12 09:17:59 +00:00
parent e2f863c151
commit d711563fe1

View File

@ -249,6 +249,7 @@ _zsh_highlight_call_widget()
_zsh_highlight_bind_widgets() _zsh_highlight_bind_widgets()
{ {
setopt localoptions noksharrays setopt localoptions noksharrays
local prefix=orig-s$SECONDS-r$RANDOM # unique each time, in case we're sourced more than once
# Load ZSH module zsh/zleparameter, needed to override user defined widgets. # Load ZSH module zsh/zleparameter, needed to override user defined widgets.
zmodload zsh/zleparameter 2>/dev/null || { zmodload zsh/zleparameter 2>/dev/null || {
@ -258,7 +259,7 @@ _zsh_highlight_bind_widgets()
# Override ZLE widgets to make them invoke _zsh_highlight. # Override ZLE widgets to make them invoke _zsh_highlight.
local -U widgets_to_bind local -U widgets_to_bind
widgets_to_bind=(${${(k)widgets}:#(.*|orig-*|run-help|which-command|beep|set-local-history|yank)}) widgets_to_bind=(${${(k)widgets}:#(.*|run-help|which-command|beep|set-local-history|yank)})
# Always wrap special zle-line-finish widget. This is needed to decide if the # Always wrap special zle-line-finish widget. This is needed to decide if the
# current line ends and special highlighting logic needs to be applied. # current line ends and special highlighting logic needs to be applied.
@ -283,13 +284,13 @@ _zsh_highlight_bind_widgets()
# NO_function_argzero, regardless of the option's setting here. # NO_function_argzero, regardless of the option's setting here.
# User defined widget: override and rebind old one with prefix "orig-". # User defined widget: override and rebind old one with prefix "orig-".
user:*) zle -N orig-$cur_widget ${widgets[$cur_widget]#*:} user:*) zle -N $prefix-$cur_widget ${widgets[$cur_widget]#*:}
eval "_zsh_highlight_widget_${(q)cur_widget}() { _zsh_highlight_call_widget orig-${(q)cur_widget} -- \"\$@\" }" eval "_zsh_highlight_widget_${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }"
zle -N $cur_widget _zsh_highlight_widget_$cur_widget;; zle -N $cur_widget _zsh_highlight_widget_$cur_widget;;
# Completion widget: override and rebind old one with prefix "orig-". # Completion widget: override and rebind old one with prefix "orig-".
completion:*) zle -C orig-$cur_widget ${${(s.:.)widgets[$cur_widget]}[2,3]} completion:*) zle -C $prefix-$cur_widget ${${(s.:.)widgets[$cur_widget]}[2,3]}
eval "_zsh_highlight_widget_${(q)cur_widget}() { _zsh_highlight_call_widget orig-${(q)cur_widget} -- \"\$@\" }" eval "_zsh_highlight_widget_${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }"
zle -N $cur_widget _zsh_highlight_widget_$cur_widget;; zle -N $cur_widget _zsh_highlight_widget_$cur_widget;;
# Builtin widget: override and make it call the builtin ".widget". # Builtin widget: override and make it call the builtin ".widget".