mirror of
https://github.com/zsh-users/zsh-autosuggestions.git
synced 2024-11-18 09:51:06 +01:00
Fix issues with widgets wrapped by other plugins
Puts in a better fix for #126 and related issues.
This commit is contained in:
parent
ea505b01e5
commit
c52c428793
3 changed files with 105 additions and 14 deletions
39
spec/integrations/wrapped_widget_spec.rb
Normal file
39
spec/integrations/wrapped_widget_spec.rb
Normal 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
|
40
src/bind.zsh
40
src/bind.zsh
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue