Files
fish-shell/tests/checks/bind.fish

182 lines
5.7 KiB
Fish
Raw Normal View History

#RUN: %fish %s
#REQUIRES: command -v diff
set -l fish (status fish-path)
set -l tmpdir (mktemp -d)
for bindings in true fish_default_key_bindings fish_vi_key_bindings
$fish -c "
$bindings
bind > $tmpdir/old
bind --erase --all --preset
bind --erase --all
source $tmpdir/old
bind >$tmpdir/new
diff -u $tmpdir/{old,new}
"
end
echo >&2 bind output evaluation works
# CHECKERR: bind output evaluation works
2019-06-26 21:10:01 +02:00
# Test various `bind` command invocations. This is meant to verify that
# invalid flags, mode names, etc. are caught as well as to verify that valid
# ones are allowed.
# Verify that an invalid bind mode is rejected.
2019-06-26 21:10:01 +02:00
bind -m 'bad bind mode' \cX true
# CHECKERR: bind: bad bind mode: invalid mode name. See `help language#shell-variable-and-function-names`
2021-11-03 22:52:17 -07:00
# Verify that an invalid bind mode target is rejected.
2019-06-26 21:10:01 +02:00
bind -M bind-mode \cX true
# CHECKERR: bind: bind-mode: invalid mode name. See `help language#shell-variable-and-function-names`
2019-06-26 21:10:01 +02:00
# This should succeed and result in a success, zero, status.
bind -M bind_mode \cX true
# Listing bindings
bind | string match -v '*\e\\[*' # Hide raw bindings.
bind --user --preset | string match -v '*\e\\[*'
2019-06-26 21:10:01 +02:00
# CHECK: bind --preset '' self-insert
# CHECK: bind --preset enter execute
# CHECK: bind --preset tab complete
# CHECK: bind --preset ctrl-c cancel-commandline
# CHECK: bind --preset ctrl-d exit
# CHECK: bind --preset ctrl-e bind
# CHECK: bind --preset ctrl-s pager-toggle-search
# CHECK: bind --preset ctrl-u backward-kill-line
# CHECK: bind --preset backspace backward-delete-char
# CHECK: bind --preset up up-line
# CHECK: bind --preset down down-line
# CHECK: bind --preset right forward-char
# CHECK: bind --preset left backward-char
# CHECK: bind --preset ctrl-p up-line
# CHECK: bind --preset ctrl-n down-line
# CHECK: bind --preset ctrl-b backward-char
# CHECK: bind --preset ctrl-f forward-char
# CHECK: bind -M bind_mode ctrl-x true
2019-06-26 21:10:01 +02:00
# CHECK: bind --preset '' self-insert
# CHECK: bind --preset enter execute
# CHECK: bind --preset tab complete
# CHECK: bind --preset ctrl-c cancel-commandline
# CHECK: bind --preset ctrl-d exit
# CHECK: bind --preset ctrl-e bind
# CHECK: bind --preset ctrl-s pager-toggle-search
# CHECK: bind --preset ctrl-u backward-kill-line
# CHECK: bind --preset backspace backward-delete-char
# CHECK: bind --preset up up-line
# CHECK: bind --preset down down-line
# CHECK: bind --preset right forward-char
# CHECK: bind --preset left backward-char
# CHECK: bind --preset ctrl-p up-line
# CHECK: bind --preset ctrl-n down-line
# CHECK: bind --preset ctrl-b backward-char
# CHECK: bind --preset ctrl-f forward-char
# CHECK: bind -M bind_mode ctrl-x true
2019-06-26 21:10:01 +02:00
# Preset only
bind --preset | string match -v '*\e\\[*'
2019-06-26 21:10:01 +02:00
# CHECK: bind --preset '' self-insert
# CHECK: bind --preset enter execute
# CHECK: bind --preset tab complete
# CHECK: bind --preset ctrl-c cancel-commandline
# CHECK: bind --preset ctrl-d exit
# CHECK: bind --preset ctrl-e bind
# CHECK: bind --preset ctrl-s pager-toggle-search
# CHECK: bind --preset ctrl-u backward-kill-line
# CHECK: bind --preset backspace backward-delete-char
# CHECK: bind --preset up up-line
# CHECK: bind --preset down down-line
# CHECK: bind --preset right forward-char
# CHECK: bind --preset left backward-char
# CHECK: bind --preset ctrl-p up-line
# CHECK: bind --preset ctrl-n down-line
# CHECK: bind --preset ctrl-b backward-char
# CHECK: bind --preset ctrl-f forward-char
2019-06-26 21:10:01 +02:00
# User only
bind --user | string match -v '*\e\\[*'
# CHECK: bind -M bind_mode ctrl-x true
2019-06-26 21:10:01 +02:00
# Adding bindings
bind tab 'echo banana'
bind | string match -v '*\e\\[*'
2019-06-26 21:10:01 +02:00
# CHECK: bind --preset '' self-insert
# CHECK: bind --preset enter execute
# CHECK: bind --preset tab complete
# CHECK: bind --preset ctrl-c cancel-commandline
# CHECK: bind --preset ctrl-d exit
# CHECK: bind --preset ctrl-e bind
# CHECK: bind --preset ctrl-s pager-toggle-search
# CHECK: bind --preset ctrl-u backward-kill-line
# CHECK: bind --preset backspace backward-delete-char
# CHECK: bind --preset up up-line
# CHECK: bind --preset down down-line
# CHECK: bind --preset right forward-char
# CHECK: bind --preset left backward-char
# CHECK: bind --preset ctrl-p up-line
# CHECK: bind --preset ctrl-n down-line
# CHECK: bind --preset ctrl-b backward-char
# CHECK: bind --preset ctrl-f forward-char
# CHECK: bind -M bind_mode ctrl-x true
# CHECK: bind tab 'echo banana'
2019-06-26 21:10:01 +02:00
bind ctrl-#
bind alt-\#
bind super-ctrl-~
bind super-alt-\~
# CHECKERR: bind: No binding found for key 'ctrl-#'
# CHECKERR: bind: No binding found for key 'alt-#'
# CHECKERR: bind: No binding found for key 'super-ctrl-~'
# CHECKERR: bind: No binding found for key 'super-alt-~'
# Legacy
bind \cx\cax 'echo foo'
bind \cx\cax
# CHECK: bind ctrl-x,ctrl-a,x 'echo foo'
bind \ef forward-word
bind \ef
# CHECK: bind alt-f forward-word
2019-06-26 21:10:01 +02:00
# Erasing bindings
bind --erase tab
bind tab
bind tab 'echo wurst'
# CHECK: bind --preset tab complete
bind --erase --user --preset tab
bind tab
# CHECKERR: bind: No binding found for key 'tab'
bind ctrl-\b
# CHECKERR: bind: Cannot add control modifier to control character 'ctrl-h'
2019-06-26 21:10:01 +02:00
bind -k nul 'echo foo'
# CHECKERR: bind: the -k/--key syntax is no longer supported. See `bind --help` and `bind --key-names`
# Either Return or ctrl-m.
bind \r
# CHECK: bind --preset enter execute
# Never Return, probably always ctrl-j.
bind \n 2>&1
# CHECK: bind: No binding found for key 'ctrl-j'
bind _\cx_\ci_\ei_\\_\'_ 'echo foo'
# CHECKERR: bind: cannot parse key '_\cx_\t_\ei_\\_'_'
Allow explicit shift modifier for non-ASCII letters, fix capslock behavior We canonicalize "ctrl-shift-i" to "ctrl-I". Both when deciphering this notation (as given to builtin bind), and when receiving it as a key event ("\e[105;73;6u") This has problems: A. Our bind notation canonicalization only works for 26 English letters. For example, "ctrl-shift-ä" is not supported -- only "ctrl-Ä" is. We could try to fix that but this depends on the keyboard layout. For example "bind alt-shift-=" and "bind alt-+" are equivalent on a "us" layout but not on a "de" layout. B. While capslock is on, the key event won't include a shifted key ("73" here). This is due a quirk in the kitty keyboard protocol[^1]. This means that fish_key_reader's canonicalization doesn't work (unless we call toupper() ourselves). I think we want to support both notations. It's recommended to match all of these (in this order) when pressing "ctrl-shift-i". 1. bind ctrl-shift-i do-something 2. bind ctrl-shift-I do-something 3. bind ctrl-I do-something 4. bind ctrl-i do-something Support 1 and 3 for now, allowing both bindings to coexist. No priorities for now. This solves problem A, and -- if we take care to use the explicit shift notation -- problem B. For keys that are not affected by capslock, problem B does not apply. In this case, recommend the shifted notation ("alt-+" instead of "alt-shift-=") since that seems more intuitive. Though if we prioritized "alt-shift-=" over "alt-+" as per the recommendation, that's an argument against the shifted key. Example output for some key events: $ fish_key_reader -cV # decoded from: \e\[61:43\;4u bind alt-+ 'do something' # recommended notation bind alt-shift-= 'do something' # decoded from: \e\[61:43\;68u bind alt-+ 'do something' # recommended notation bind alt-shift-= 'do something' # decoded from: \e\[105:73\;6u bind ctrl-I 'do something' bind ctrl-shift-i 'do something' # recommended notation # decoded from: \e\[105\;70u bind ctrl-shift-i 'do something' Due to the capslock quirk, the last one has only one matching representation since there is no shifted key. We could decide to match ctrl-shift-i events (that don't have a shifted key) to ctrl-I bindings (for ASCII letters), as before this patch. But that case is very rare, it should only happen when capslock is on, so it's probably not even a breaking change. The other way round is supported -- we do match ctrl-I events (typically with shifted key) to ctrl-shift-i bindings (but only for ASCII letters). This is mainly for backwards compatibility. Also note that, bindings without other modifiers currently need to use the shifted key (like "Ä", not "shift-ä"), since we still get a legacy encoding, until we request "Report all keys as escape codes". [^1]: <https://github.com/kovidgoyal/kitty/issues/8493>
2025-03-30 08:33:24 +02:00
bind A
# CHECKERR: bind: No binding found for key 'A'
bind shift-a
# CHECKERR: bind: No binding found for key 'shift-a'
bind shift-A
# CHECKERR: bind: No binding found for key 'shift-A'
bind ctrl-shift-a
# CHECKERR: bind: No binding found for key 'ctrl-shift-a'
bind ctrl-shift-ä
# CHECKERR: bind: No binding found for key 'ctrl-shift-ä'
2019-06-26 21:10:01 +02:00
exit 0