Fix issues with widgets wrapped by other plugins

Puts in a better fix for #126 and related issues.
This commit is contained in:
Eric Freese 2017-02-28 11:14:16 -07:00
parent ea505b01e5
commit c52c428793
3 changed files with 105 additions and 14 deletions

View file

@ -0,0 +1,39 @@
describe 'a wrapped widget' do
let(:widget) { 'backward-delete-char' }
context 'initialized before sourcing the plugin' do
let(:before_sourcing) do
-> do
session.
run_command("_orig_#{widget}() { zle .#{widget} }").
run_command("zle -N orig-#{widget} _orig_#{widget}").
run_command("#{widget}-magic() { zle orig-#{widget}; BUFFER+=b }").
run_command("zle -N #{widget} #{widget}-magic")
end
end
it 'executes the custom behavior and the built-in behavior' do
with_history('foobar', 'foodar') do
session.send_string('food').send_keys('C-h')
wait_for { session.content }.to eq('foobar')
end
end
end
context 'initialized after sourcing the plugin' do
before do
session.
run_command("zle -N orig-#{widget} ${widgets[#{widget}]#*:}").
run_command("#{widget}-magic() { zle orig-#{widget}; BUFFER+=b }").
run_command("zle -N #{widget} #{widget}-magic").
clear_screen
end
it 'executes the custom behavior and the built-in behavior' do
with_history('foobar', 'foodar') do
session.send_string('food').send_keys('C-h')
wait_for { session.content }.to eq('foobar')
end
end
end
end

View file

@ -3,12 +3,34 @@
# Widget Helpers # # Widget Helpers #
#--------------------------------------------------------------------# #--------------------------------------------------------------------#
_zsh_autosuggest_incr_bind_count() {
if ((${+_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]})); then
((_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]++))
else
_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]=1
fi
bind_count=$_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]
}
_zsh_autosuggest_get_bind_count() {
if ((${+_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]})); then
bind_count=$_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]
else
bind_count=0
fi
}
# Bind a single widget to an autosuggest widget, saving a reference to the original widget # Bind a single widget to an autosuggest widget, saving a reference to the original widget
_zsh_autosuggest_bind_widget() { _zsh_autosuggest_bind_widget() {
typeset -gA _ZSH_AUTOSUGGEST_BIND_COUNTS
local widget=$1 local widget=$1
local autosuggest_action=$2 local autosuggest_action=$2
local prefix=$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX local prefix=$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX
local -i bind_count
# Save a reference to the original widget # Save a reference to the original widget
case $widgets[$widget] in case $widgets[$widget] in
# Already bound # Already bound
@ -16,34 +38,38 @@ _zsh_autosuggest_bind_widget() {
# User-defined widget # User-defined widget
user:*) user:*)
zle -l "$prefix$widget" && zle -N "$widget" ${widgets[$prefix$widget]#*:} _zsh_autosuggest_incr_bind_count $widget
zle -N $prefix$widget ${widgets[$widget]#*:} zle -N $prefix${bind_count}-$widget ${widgets[$widget]#*:}
;; ;;
# Built-in widget # Built-in widget
builtin) builtin)
_zsh_autosuggest_incr_bind_count $widget
eval "_zsh_autosuggest_orig_${(q)widget}() { zle .${(q)widget} }" eval "_zsh_autosuggest_orig_${(q)widget}() { zle .${(q)widget} }"
zle -N $prefix$widget _zsh_autosuggest_orig_$widget zle -N $prefix${bind_count}-$widget _zsh_autosuggest_orig_$widget
;; ;;
# Completion widget # Completion widget
completion:*) completion:*)
eval "zle -C $prefix${(q)widget} ${${(s.:.)widgets[$widget]}[2,3]}" _zsh_autosuggest_incr_bind_count $widget
eval "zle -C $prefix${bind_count}-${(q)widget} ${${(s.:.)widgets[$widget]}[2,3]}"
;; ;;
esac esac
_zsh_autosuggest_get_bind_count $widget
# Pass the original widget's name explicitly into the autosuggest # Pass the original widget's name explicitly into the autosuggest
# function. Use this passed in widget name to call the original # function. Use this passed in widget name to call the original
# widget instead of relying on the $WIDGET variable being set # widget instead of relying on the $WIDGET variable being set
# correctly. $WIDGET cannot be trusted because other plugins call # correctly. $WIDGET cannot be trusted because other plugins call
# zle without the `-w` flag (e.g. `zle self-insert` instead of # zle without the `-w` flag (e.g. `zle self-insert` instead of
# `zle self-insert -w`). # `zle self-insert -w`).
eval "_zsh_autosuggest_bound_${(q)widget}() { eval "_zsh_autosuggest_bound_${bind_count}_${(q)widget}() {
_zsh_autosuggest_widget_$autosuggest_action $prefix${(q)widget} \$@ _zsh_autosuggest_widget_$autosuggest_action $prefix$bind_count-${(q)widget} \$@
}" }"
# Create the bound widget # Create the bound widget
zle -N $widget _zsh_autosuggest_bound_$widget zle -N $widget _zsh_autosuggest_bound_${bind_count}_$widget
} }
# Map all configured widgets to the right autosuggest widgets # Map all configured widgets to the right autosuggest widgets

View file

@ -137,12 +137,34 @@ _zsh_autosuggest_feature_detect_zpty_returns_fd() {
# Widget Helpers # # Widget Helpers #
#--------------------------------------------------------------------# #--------------------------------------------------------------------#
_zsh_autosuggest_incr_bind_count() {
if ((${+_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]})); then
((_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]++))
else
_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]=1
fi
bind_count=$_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]
}
_zsh_autosuggest_get_bind_count() {
if ((${+_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]})); then
bind_count=$_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]
else
bind_count=0
fi
}
# Bind a single widget to an autosuggest widget, saving a reference to the original widget # Bind a single widget to an autosuggest widget, saving a reference to the original widget
_zsh_autosuggest_bind_widget() { _zsh_autosuggest_bind_widget() {
typeset -gA _ZSH_AUTOSUGGEST_BIND_COUNTS
local widget=$1 local widget=$1
local autosuggest_action=$2 local autosuggest_action=$2
local prefix=$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX local prefix=$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX
local -i bind_count
# Save a reference to the original widget # Save a reference to the original widget
case $widgets[$widget] in case $widgets[$widget] in
# Already bound # Already bound
@ -150,34 +172,38 @@ _zsh_autosuggest_bind_widget() {
# User-defined widget # User-defined widget
user:*) user:*)
zle -l "$prefix$widget" && zle -N "$widget" ${widgets[$prefix$widget]#*:} _zsh_autosuggest_incr_bind_count $widget
zle -N $prefix$widget ${widgets[$widget]#*:} zle -N $prefix${bind_count}-$widget ${widgets[$widget]#*:}
;; ;;
# Built-in widget # Built-in widget
builtin) builtin)
_zsh_autosuggest_incr_bind_count $widget
eval "_zsh_autosuggest_orig_${(q)widget}() { zle .${(q)widget} }" eval "_zsh_autosuggest_orig_${(q)widget}() { zle .${(q)widget} }"
zle -N $prefix$widget _zsh_autosuggest_orig_$widget zle -N $prefix${bind_count}-$widget _zsh_autosuggest_orig_$widget
;; ;;
# Completion widget # Completion widget
completion:*) completion:*)
eval "zle -C $prefix${(q)widget} ${${(s.:.)widgets[$widget]}[2,3]}" _zsh_autosuggest_incr_bind_count $widget
eval "zle -C $prefix${bind_count}-${(q)widget} ${${(s.:.)widgets[$widget]}[2,3]}"
;; ;;
esac esac
_zsh_autosuggest_get_bind_count $widget
# Pass the original widget's name explicitly into the autosuggest # Pass the original widget's name explicitly into the autosuggest
# function. Use this passed in widget name to call the original # function. Use this passed in widget name to call the original
# widget instead of relying on the $WIDGET variable being set # widget instead of relying on the $WIDGET variable being set
# correctly. $WIDGET cannot be trusted because other plugins call # correctly. $WIDGET cannot be trusted because other plugins call
# zle without the `-w` flag (e.g. `zle self-insert` instead of # zle without the `-w` flag (e.g. `zle self-insert` instead of
# `zle self-insert -w`). # `zle self-insert -w`).
eval "_zsh_autosuggest_bound_${(q)widget}() { eval "_zsh_autosuggest_bound_${bind_count}_${(q)widget}() {
_zsh_autosuggest_widget_$autosuggest_action $prefix${(q)widget} \$@ _zsh_autosuggest_widget_$autosuggest_action $prefix$bind_count-${(q)widget} \$@
}" }"
# Create the bound widget # Create the bound widget
zle -N $widget _zsh_autosuggest_bound_$widget zle -N $widget _zsh_autosuggest_bound_${bind_count}_$widget
} }
# Map all configured widgets to the right autosuggest widgets # Map all configured widgets to the right autosuggest widgets