mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 20:33:08 +00:00
Reset fish_bind_mode when changing fish_key_bindings
Also avoid resetting bindings if fish_key_bindings is "modified" without actually changing. Fixes #1638.
This commit is contained in:
parent
174f5ba99a
commit
0a32d96b27
9 changed files with 107 additions and 20 deletions
|
@ -205,6 +205,14 @@ function __fish_config_interactive -d "Initializations that should be performed
|
||||||
|
|
||||||
# Reload key bindings when binding variable change
|
# Reload key bindings when binding variable change
|
||||||
function __fish_reload_key_bindings -d "Reload key bindings when binding variable change" --on-variable fish_key_bindings
|
function __fish_reload_key_bindings -d "Reload key bindings when binding variable change" --on-variable fish_key_bindings
|
||||||
|
# do nothing if the key bindings didn't actually change
|
||||||
|
# This could be because the variable was set to the existing value
|
||||||
|
# or because it was a local variable
|
||||||
|
if test "$fish_key_bindings" = "$__fish_active_key_bindings"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
set -g __fish_active_key_bindings "$fish_key_bindings"
|
||||||
|
set -g fish_bind_mode default
|
||||||
# Do something nasty to avoid two forks
|
# Do something nasty to avoid two forks
|
||||||
if test "$fish_key_bindings" = fish_default_key_bindings
|
if test "$fish_key_bindings" = fish_default_key_bindings
|
||||||
fish_default_key_bindings
|
fish_default_key_bindings
|
||||||
|
|
43
tests/bind.expect
Normal file
43
tests/bind.expect
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# vim: set filetype=expect:
|
||||||
|
|
||||||
|
spawn $fish
|
||||||
|
|
||||||
|
expect_prompt
|
||||||
|
|
||||||
|
# test switching key bindings
|
||||||
|
# this should leave the mode in the appropriate state
|
||||||
|
|
||||||
|
send_line "set -g fish_key_bindings fish_vi_key_bindings"
|
||||||
|
expect_prompt
|
||||||
|
send_line -h "echo fail\033ddiecho success"
|
||||||
|
expect_prompt -re {\r\nsuccess\r\n} {
|
||||||
|
puts "success"
|
||||||
|
} -nounmatched -re {\r\nfail} {
|
||||||
|
puts stderr "fail"
|
||||||
|
} unmatched {
|
||||||
|
puts stderr "Couldn't find expected output 'success'"
|
||||||
|
}
|
||||||
|
# try again without the human typing
|
||||||
|
send_line "echo fail\033ddiecho success"
|
||||||
|
expect_prompt -re {\r\nsuccess\r\n} {
|
||||||
|
puts "success"
|
||||||
|
} -nounmatched -re {\r\nfail} {
|
||||||
|
puts stderr "fail"
|
||||||
|
} unmatched {
|
||||||
|
puts stderr "Couldn't find expected output 'success'"
|
||||||
|
}
|
||||||
|
|
||||||
|
# still in insert mode, switch back to regular key bindings
|
||||||
|
send_line "set -g fish_key_bindings fish_default_key_bindings"
|
||||||
|
expect_prompt
|
||||||
|
send_line "echo success"
|
||||||
|
expect_prompt -re {\r\nsuccess\r\n} {
|
||||||
|
puts "success"
|
||||||
|
} unmatched {
|
||||||
|
puts stderr "Couldn't find expected output 'success'"
|
||||||
|
} timeout {
|
||||||
|
set msg ""
|
||||||
|
append msg "Timeout after setting fish_key_bindings to fish_default_key_bindings\n" \
|
||||||
|
"\$fish_bind_mode is most likely still set to 'insert'"
|
||||||
|
abort $msg
|
||||||
|
}
|
0
tests/bind.expect.err
Normal file
0
tests/bind.expect.err
Normal file
3
tests/bind.expect.out
Normal file
3
tests/bind.expect.out
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
success
|
||||||
|
success
|
||||||
|
success
|
1
tests/bind.expect.status
Normal file
1
tests/bind.expect.status
Normal file
|
@ -0,0 +1 @@
|
||||||
|
0
|
|
@ -1,13 +1,16 @@
|
||||||
# vim: set filetype=fish sw=4 ts=4 et:
|
# vim: set filetype=fish sw=4 ts=4 et:
|
||||||
|
|
||||||
set -g prompt_counter 1
|
# source the non-interactive config
|
||||||
|
source $XDG_CONFIG_HOME/../tmp.config/fish/config.fish
|
||||||
|
|
||||||
|
set -g prompt_counter 0
|
||||||
set -g prompt_counter_incr 0
|
set -g prompt_counter_incr 0
|
||||||
function fish_prompt
|
function fish_prompt
|
||||||
echo "prompt $prompt_counter>"
|
|
||||||
if test $prompt_counter_incr -eq 1
|
if test $prompt_counter_incr -eq 1
|
||||||
set -g prompt_counter (expr $prompt_counter + 1)
|
set -g prompt_counter (expr $prompt_counter + 1)
|
||||||
set -g prompt_counter_incr 0
|
set -g prompt_counter_incr 0
|
||||||
end
|
end
|
||||||
|
echo "prompt $prompt_counter>"
|
||||||
end
|
end
|
||||||
function fish_prompt_event --on-event fish_prompt
|
function fish_prompt_event --on-event fish_prompt
|
||||||
set -g prompt_counter_incr 1
|
set -g prompt_counter_incr 1
|
||||||
|
|
|
@ -42,17 +42,24 @@ proc log_debug string {
|
||||||
set prompt_counter 1
|
set prompt_counter 1
|
||||||
# expect_prompt takes an argument list like `expect` does.
|
# expect_prompt takes an argument list like `expect` does.
|
||||||
# It supports a special pattern "unmatched" that is run if no
|
# It supports a special pattern "unmatched" that is run if no
|
||||||
# other provided patterns match.
|
# other provided patterns match, and a special flag "-nounmatched"
|
||||||
|
# that marks the following pattern as not being tracked for
|
||||||
|
# "unmatched" handling.
|
||||||
|
# If multiple patterns are provided, they may all match. Each pattern
|
||||||
|
# is matched at most once. The matching only ends once the prompt is
|
||||||
|
# found.
|
||||||
proc expect_prompt {args} {
|
proc expect_prompt {args} {
|
||||||
global prompt_counter
|
global prompt_counter
|
||||||
upvar expect_out expect_out
|
upvar expect_out expect_out
|
||||||
set prompt_pat [list -re "(?:\\r\\n?|^)prompt $prompt_counter>(?:$|\r)"]
|
set prompt_pat [list -re "(?:\\r\\n?|^)prompt $prompt_counter>(?:$|\\r)"]
|
||||||
if {[llength $args] == 1 && [string match "\n*" $args]} {
|
if {[llength $args] == 1 && [string match "\n*" $args]} {
|
||||||
set args [join $args]
|
set args [join $args]
|
||||||
}
|
}
|
||||||
set prompt_action ""
|
set prompt_action ""
|
||||||
set expargs {}
|
set expargs {}
|
||||||
upvar expect_out up_expect_out
|
set nounmatched no
|
||||||
|
set matchidx 0
|
||||||
|
set matched(any) no
|
||||||
set state "firstarg"
|
set state "firstarg"
|
||||||
foreach arg $args {
|
foreach arg $args {
|
||||||
switch $state {
|
switch $state {
|
||||||
|
@ -63,14 +70,17 @@ proc expect_prompt {args} {
|
||||||
"action" {
|
"action" {
|
||||||
lappend expargs [subst -nocommands {
|
lappend expargs [subst -nocommands {
|
||||||
log_debug "matched extra pattern to expect_prompt: [quote \$expect_out(0,string)]"
|
log_debug "matched extra pattern to expect_prompt: [quote \$expect_out(0,string)]"
|
||||||
if {\$matched} {
|
if {!\$matched($matchidx)} {
|
||||||
exp_continue
|
set matched($matchidx) yes
|
||||||
}
|
if {!$nounmatched} { set matched(any) yes }
|
||||||
set matched yes
|
|
||||||
uplevel 1 {$arg}
|
uplevel 1 {$arg}
|
||||||
|
}
|
||||||
exp_continue
|
exp_continue
|
||||||
}]
|
}]
|
||||||
|
set matched($matchidx) no
|
||||||
|
incr matchidx
|
||||||
set state "firstarg"
|
set state "firstarg"
|
||||||
|
set nounmatched no
|
||||||
}
|
}
|
||||||
"firstarg" -
|
"firstarg" -
|
||||||
"arg" {
|
"arg" {
|
||||||
|
@ -78,8 +88,8 @@ proc expect_prompt {args} {
|
||||||
set state "unmatched"
|
set state "unmatched"
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
lappend expargs $arg
|
set keep yes
|
||||||
switch $arg {
|
switch -glob -- $arg {
|
||||||
-gl -
|
-gl -
|
||||||
-re -
|
-re -
|
||||||
-ex {
|
-ex {
|
||||||
|
@ -89,6 +99,20 @@ proc expect_prompt {args} {
|
||||||
-timeout {
|
-timeout {
|
||||||
set state "flagarg"
|
set state "flagarg"
|
||||||
}
|
}
|
||||||
|
-nounmatched {
|
||||||
|
set keep no
|
||||||
|
set nounmatched yes
|
||||||
|
set state "arg"
|
||||||
|
}
|
||||||
|
-* {
|
||||||
|
error "BUG: unknown expect flag in expect_prompt"
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
set state "pat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if {$keep} {
|
||||||
|
lappend expargs $arg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"flagarg" {
|
"flagarg" {
|
||||||
|
@ -96,9 +120,11 @@ proc expect_prompt {args} {
|
||||||
set state "arg"
|
set state "arg"
|
||||||
}
|
}
|
||||||
"unmatched" {
|
"unmatched" {
|
||||||
|
set state "firstarg"
|
||||||
if {$prompt_action ne ""} continue
|
if {$prompt_action ne ""} continue
|
||||||
set prompt_action [subst -nocommands {
|
set prompt_action [subst -nocommands {
|
||||||
if {!\$matched} {
|
if {!\$matched(any)} {
|
||||||
|
log_debug "triggered unmatched action in expect_prompt"
|
||||||
uplevel 1 {$arg}
|
uplevel 1 {$arg}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
@ -114,7 +140,6 @@ proc expect_prompt {args} {
|
||||||
log_info "expecting prompt $prompt_counter"
|
log_info "expecting prompt $prompt_counter"
|
||||||
}
|
}
|
||||||
set expargs [concat $prompt_pat [list $prompt_action] $expargs]
|
set expargs [concat $prompt_pat [list $prompt_action] $expargs]
|
||||||
set matched no
|
|
||||||
expect {*}$expargs
|
expect {*}$expargs
|
||||||
incr prompt_counter
|
incr prompt_counter
|
||||||
}
|
}
|
||||||
|
@ -128,6 +153,7 @@ proc trace_expect {cmd args} {
|
||||||
switch [lindex $args end] {
|
switch [lindex $args end] {
|
||||||
enter {
|
enter {
|
||||||
log_debug "entering expect"
|
log_debug "entering expect"
|
||||||
|
log_debug "command: $cmd"
|
||||||
uplevel {set expect_out(buffer) {}}
|
uplevel {set expect_out(buffer) {}}
|
||||||
}
|
}
|
||||||
leave {
|
leave {
|
||||||
|
@ -160,7 +186,7 @@ proc trace_spawn {cmd args} {
|
||||||
}
|
}
|
||||||
leave {
|
leave {
|
||||||
log_debug "[quote $cmd]: code [lindex $args 0], result [lindex $args 1]"
|
log_debug "[quote $cmd]: code [lindex $args 0], result [lindex $args 1]"
|
||||||
expect_before {
|
expect_after {
|
||||||
timeout {
|
timeout {
|
||||||
expect "*" {
|
expect "*" {
|
||||||
log_debug "timeout; buffer=[quote $expect_out(buffer)]"
|
log_debug "timeout; buffer=[quote $expect_out(buffer)]"
|
||||||
|
@ -216,7 +242,6 @@ proc print_var_contents name {
|
||||||
|
|
||||||
# match on the results
|
# match on the results
|
||||||
set pat {\r\n@GUARD:$guard@\r\n(.*)\r\n@/GUARD:$guard@\r\n}
|
set pat {\r\n@GUARD:$guard@\r\n(.*)\r\n@/GUARD:$guard@\r\n}
|
||||||
set matched false
|
|
||||||
expect_prompt -re [subst -nocommands -nobackslashes $pat] {
|
expect_prompt -re [subst -nocommands -nobackslashes $pat] {
|
||||||
log_info "get_var_contents: result: [quote $expect_out(1,string)]"
|
log_info "get_var_contents: result: [quote $expect_out(1,string)]"
|
||||||
puts $expect_out(1,string)
|
puts $expect_out(1,string)
|
||||||
|
|
|
@ -15,20 +15,21 @@ for i in *.expect
|
||||||
begin
|
begin
|
||||||
set -lx XDG_CONFIG_HOME $PWD/tmp.interactive.config
|
set -lx XDG_CONFIG_HOME $PWD/tmp.interactive.config
|
||||||
set -lx TERM dumb
|
set -lx TERM dumb
|
||||||
expect -n -c 'source interactive.expect.rc' -f $i >tmp.out ^tmp.err
|
expect -n -c 'source interactive.expect.rc' -f $i >$i.tmp.out ^$i.tmp.err
|
||||||
end
|
end
|
||||||
set -l tmp_status $status
|
set -l tmp_status $status
|
||||||
set res ok
|
set res ok
|
||||||
if not diff tmp.out $i.out >/dev/null
|
mv -f interactive.tmp.log $i.tmp.log
|
||||||
|
if not diff $i.tmp.out $i.out >/dev/null
|
||||||
set res fail
|
set res fail
|
||||||
echo "Output differs for file $i. Diff follows:"
|
echo "Output differs for file $i. Diff follows:"
|
||||||
diff -u tmp.out $i.out
|
diff -u $i.tmp.out $i.out
|
||||||
end
|
end
|
||||||
|
|
||||||
if not diff tmp.err $i.err >/dev/null
|
if not diff $i.tmp.err $i.err >/dev/null
|
||||||
set res fail
|
set res fail
|
||||||
echo "Error output differs for file $i. Diff follows:"
|
echo "Error output differs for file $i. Diff follows:"
|
||||||
diff -u tmp.err $i.err
|
diff -u $i.tmp.err $i.err
|
||||||
end
|
end
|
||||||
|
|
||||||
if test $tmp_status != (cat $i.status)
|
if test $tmp_status != (cat $i.status)
|
||||||
|
@ -38,6 +39,8 @@ for i in *.expect
|
||||||
|
|
||||||
if test $res = ok
|
if test $res = ok
|
||||||
echo "File $i tested ok"
|
echo "File $i tested ok"
|
||||||
|
# clean up tmp files
|
||||||
|
rm -f $i.tmp.{err,out,log}
|
||||||
else
|
else
|
||||||
echo "File $i failed tests"
|
echo "File $i failed tests"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
|
File bind.expect tested ok
|
||||||
File read.expect tested ok
|
File read.expect tested ok
|
||||||
|
|
Loading…
Reference in a new issue