Skip to content

Commit

Permalink
Add separation of "preset" bindings
Browse files Browse the repository at this point in the history
This allows for marking certain bindings as part of a preset, which allows us to

- only erase those when switching presets
- go back to the preset binding when erasing a user binding
- only show user customization if requested
- make bare bind statements in config.fish work (!!!11elf!!!)

Fixes fish-shell#5191.
Fixes fish-shell#3699.
  • Loading branch information
faho authored and ridiculousfish committed Nov 23, 2018
1 parent c345e85 commit 5e646b3
Show file tree
Hide file tree
Showing 12 changed files with 538 additions and 363 deletions.
10 changes: 7 additions & 3 deletions doc_src/bind.txt
Expand Up @@ -3,12 +3,14 @@
\subsection bind-synopsis Synopsis
\fish{synopsis}
bind [(-M | --mode) MODE] [(-m | --sets-mode) NEW_MODE]
[--preset | --user]
[(-s | --silent)] [(-k | --key)] SEQUENCE COMMAND [COMMAND...]
bind [(-M | --mode) MODE] [(-k | --key)] SEQUENCE
bind (-K | --key-names) [(-a | --all)]
bind [(-M | --mode) MODE] [(-k | --key)] [--preset] [--user] SEQUENCE
bind (-K | --key-names) [(-a | --all)] [--preset] [--user]
bind (-f | --function-names)
bind (-L | --list-modes)
bind (-e | --erase) [(-M | --mode) MODE]
[--preset] [--user]
(-a | --all | [(-k | --key)] SEQUENCE [SEQUENCE...])
\endfish

Expand All @@ -32,7 +34,7 @@ When multiple `COMMAND`s are provided, they are all run in the specified order w

If no `SEQUENCE` is provided, all bindings (or just the bindings in the specified `MODE`) are printed. If `SEQUENCE` is provided without `COMMAND`, just the binding matching that sequence is printed.

Key bindings are not saved between sessions by default. **Bare `bind` statements in <a href="index.html#initialization">config.fish</a> won't have any effect because it is sourced before the default keybindings are setup.** To save custom keybindings, put the `bind` statements into a function called `fish_user_key_bindings`, which will be <a href="tutorial.html#tut_autoload">autoloaded</a>.
To save custom keybindings, put the `bind` statements into <a href="index.html#initialization">config.fish</a>. Alternatively, fish also automatically executes a function called `fish_user_key_bindings` if it exists.

Key bindings may use "modes", which mimics Vi's modal input behavior. The default mode is "default", and every bind applies to a single mode. The mode can be viewed/changed with the `$fish_bind_mode` variable.

Expand All @@ -54,6 +56,8 @@ The following parameters are available:

- `-a` or `--all` See `--erase` and `--key-names`

- `--preset` and `--user` specify if bind should operate on user or preset bindings. User bindings take precedence over preset bindings when fish looks up mappings. By default, all `bind` invocations work on the "user" level except for listing, which will show both levels. All invocations except for inserting new bindings can operate on both levels at the same time. `--preset` should only be used in full binding sets (like when working on `fish_vi_key_bindings`).

\subsection bind-functions Special input functions
The following special input functions are available:

Expand Down
142 changes: 71 additions & 71 deletions share/functions/__fish_shared_key_bindings.fish
Expand Up @@ -9,103 +9,103 @@ function __fish_shared_key_bindings -d "Bindings shared between emacs and vi mod
return 1
end

bind $argv \cy yank
bind --preset $argv \cy yank
or return # protect against invalid $argv
bind $argv \ey yank-pop
bind --preset $argv \ey yank-pop

# Left/Right arrow
bind $argv -k right forward-char
bind $argv -k left backward-char
bind $argv \e\[C forward-char
bind $argv \e\[D backward-char
bind --preset $argv -k right forward-char
bind --preset $argv -k left backward-char
bind --preset $argv \e\[C forward-char
bind --preset $argv \e\[D backward-char
# Some terminals output these when they're in in keypad mode.
bind $argv \eOC forward-char
bind $argv \eOD backward-char
bind --preset $argv \eOC forward-char
bind --preset $argv \eOD backward-char

bind $argv -k ppage beginning-of-history
bind $argv -k npage end-of-history
bind --preset $argv -k ppage beginning-of-history
bind --preset $argv -k npage end-of-history

# Interaction with the system clipboard.
bind $argv \cx fish_clipboard_copy
bind $argv \cv fish_clipboard_paste
bind --preset $argv \cx fish_clipboard_copy
bind --preset $argv \cv fish_clipboard_paste

bind $argv \e cancel
bind $argv \t complete
bind $argv \cs pager-toggle-search
bind --preset $argv \e cancel
bind --preset $argv \t complete
bind --preset $argv \cs pager-toggle-search
# shift-tab does a tab complete followed by a search.
bind $argv --key btab complete-and-search
bind --preset $argv --key btab complete-and-search

bind $argv \e\n "commandline -i \n"
bind $argv \e\r "commandline -i \n"
bind --preset $argv \e\n "commandline -i \n"
bind --preset $argv \e\r "commandline -i \n"

bind $argv -k down down-or-search
bind $argv -k up up-or-search
bind $argv \e\[A up-or-search
bind $argv \e\[B down-or-search
bind $argv \eOA up-or-search
bind $argv \eOB down-or-search
bind --preset $argv -k down down-or-search
bind --preset $argv -k up up-or-search
bind --preset $argv \e\[A up-or-search
bind --preset $argv \e\[B down-or-search
bind --preset $argv \eOA up-or-search
bind --preset $argv \eOB down-or-search

# Alt-left/Alt-right
bind $argv \e\eOC nextd-or-forward-word
bind $argv \e\eOD prevd-or-backward-word
bind $argv \e\e\[C nextd-or-forward-word
bind $argv \e\e\[D prevd-or-backward-word
bind $argv \eO3C nextd-or-forward-word
bind $argv \eO3D prevd-or-backward-word
bind $argv \e\[3C nextd-or-forward-word
bind $argv \e\[3D prevd-or-backward-word
bind $argv \e\[1\;3C nextd-or-forward-word
bind $argv \e\[1\;3D prevd-or-backward-word
bind $argv \e\[1\;9C nextd-or-forward-word #iTerm2
bind $argv \e\[1\;9D prevd-or-backward-word #iTerm2
bind --preset $argv \e\eOC nextd-or-forward-word
bind --preset $argv \e\eOD prevd-or-backward-word
bind --preset $argv \e\e\[C nextd-or-forward-word
bind --preset $argv \e\e\[D prevd-or-backward-word
bind --preset $argv \eO3C nextd-or-forward-word
bind --preset $argv \eO3D prevd-or-backward-word
bind --preset $argv \e\[3C nextd-or-forward-word
bind --preset $argv \e\[3D prevd-or-backward-word
bind --preset $argv \e\[1\;3C nextd-or-forward-word
bind --preset $argv \e\[1\;3D prevd-or-backward-word
bind --preset $argv \e\[1\;9C nextd-or-forward-word #iTerm2
bind --preset $argv \e\[1\;9D prevd-or-backward-word #iTerm2

# Alt-up/Alt-down
bind $argv \e\eOA history-token-search-backward
bind $argv \e\eOB history-token-search-forward
bind $argv \e\e\[A history-token-search-backward
bind $argv \e\e\[B history-token-search-forward
bind $argv \eO3A history-token-search-backward
bind $argv \eO3B history-token-search-forward
bind $argv \e\[3A history-token-search-backward
bind $argv \e\[3B history-token-search-forward
bind $argv \e\[1\;3A history-token-search-backward
bind $argv \e\[1\;3B history-token-search-forward
bind $argv \e\[1\;9A history-token-search-backward # iTerm2
bind $argv \e\[1\;9B history-token-search-forward # iTerm2
bind --preset $argv \e\eOA history-token-search-backward
bind --preset $argv \e\eOB history-token-search-forward
bind --preset $argv \e\e\[A history-token-search-backward
bind --preset $argv \e\e\[B history-token-search-forward
bind --preset $argv \eO3A history-token-search-backward
bind --preset $argv \eO3B history-token-search-forward
bind --preset $argv \e\[3A history-token-search-backward
bind --preset $argv \e\[3B history-token-search-forward
bind --preset $argv \e\[1\;3A history-token-search-backward
bind --preset $argv \e\[1\;3B history-token-search-forward
bind --preset $argv \e\[1\;9A history-token-search-backward # iTerm2
bind --preset $argv \e\[1\;9B history-token-search-forward # iTerm2
# Bash compatibility
# https://github.com/fish-shell/fish-shell/issues/89
bind $argv \e. history-token-search-backward
bind --preset $argv \e. history-token-search-backward

bind $argv \el __fish_list_current_token
bind $argv \ew 'set tok (commandline -pt); if test $tok[1]; echo; whatis $tok[1]; commandline -f repaint; end'
bind --preset $argv \el __fish_list_current_token
bind --preset $argv \ew 'set tok (commandline -pt); if test $tok[1]; echo; whatis $tok[1]; commandline -f repaint; end'
# ncurses > 6.0 sends a "delete scrollback" sequence along with clear.
# This string replace removes it.
bind $argv \cl 'echo -n (clear | string replace \e\[3J ""); commandline -f repaint'
bind $argv \cc __fish_cancel_commandline
bind $argv \cu backward-kill-line
bind $argv \cw backward-kill-path-component
bind $argv \e\[F end-of-line
bind $argv \e\[H beginning-of-line
bind --preset $argv \cl 'echo -n (clear | string replace \e\[3J ""); commandline -f repaint'
bind --preset $argv \cc __fish_cancel_commandline
bind --preset $argv \cu backward-kill-line
bind --preset $argv \cw backward-kill-path-component
bind --preset $argv \e\[F end-of-line
bind --preset $argv \e\[H beginning-of-line

bind $argv \ed 'set -l cmd (commandline); if test -z "$cmd"; echo; dirh; commandline -f repaint; else; commandline -f kill-word; end'
bind $argv \cd delete-or-exit
bind --preset $argv \ed 'set -l cmd (commandline); if test -z "$cmd"; echo; dirh; commandline -f repaint; else; commandline -f kill-word; end'
bind --preset $argv \cd delete-or-exit

# Allow reading manpages by pressing F1 (many GUI applications) or Alt+h (like in zsh).
bind $argv -k f1 __fish_man_page
bind $argv \eh __fish_man_page
bind --preset $argv -k f1 __fish_man_page
bind --preset $argv \eh __fish_man_page

# This will make sure the output of the current command is paged using the default pager when
# you press Meta-p.
# If none is set, less will be used.
bind $argv \ep '__fish_paginate'
bind --preset $argv \ep '__fish_paginate'

# Make it easy to turn an unexecuted command into a comment in the shell history. Also,
# remove the commenting chars so the command can be further edited then executed.
bind $argv \e\# __fish_toggle_comment_commandline
bind --preset $argv \e\# __fish_toggle_comment_commandline

# The [meta-e] and [meta-v] keystrokes invoke an external editor on the command buffer.
bind \ee edit_command_buffer
bind \ev edit_command_buffer
bind --preset $argv \ee edit_command_buffer
bind --preset $argv \ev edit_command_buffer

# Support for "bracketed paste"
# The way it works is that we acknowledge our support by printing
Expand Down Expand Up @@ -135,17 +135,17 @@ function __fish_shared_key_bindings -d "Bindings shared between emacs and vi mod

# Exclude paste mode or there'll be an additional binding after switching between emacs and vi
for mode in (bind --list-modes | string match -v paste)
bind -M $mode -m paste \e\[200~ '__fish_start_bracketed_paste'
bind --preset -M $mode -m paste \e\[200~ '__fish_start_bracketed_paste'
end
# This sequence ends paste-mode and returns to the previous mode we have saved before.
bind -M paste \e\[201~ '__fish_stop_bracketed_paste'
bind --preset -M paste \e\[201~ '__fish_stop_bracketed_paste'
# In paste-mode, everything self-inserts except for the sequence to get out of it
bind -M paste "" self-insert
bind --preset -M paste "" self-insert
# Without this, a \r will overwrite the other text, rendering it invisible - which makes the exercise kinda pointless.
# TODO: Test this in windows (\r\n line endings)
bind -M paste \r "commandline -i \n"
bind -M paste "'" "__fish_commandline_insert_escaped \' \$__fish_paste_quoted"
bind -M paste \\ "__fish_commandline_insert_escaped \\\ \$__fish_paste_quoted"
bind --preset -M paste \r "commandline -i \n"
bind --preset -M paste "'" "__fish_commandline_insert_escaped \' \$__fish_paste_quoted"
bind --preset -M paste \\ "__fish_commandline_insert_escaped \\\ \$__fish_paste_quoted"
end

function __fish_commandline_insert_escaped --description 'Insert the first arg escaped if a second arg is given'
Expand Down
94 changes: 47 additions & 47 deletions share/functions/fish_default_key_bindings.fish
Expand Up @@ -6,7 +6,7 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis
end

if not set -q argv[1]
bind --erase --all # clear earlier bindings, if any
bind --erase --all --preset # clear earlier bindings, if any
if test "$fish_key_bindings" != "fish_default_key_bindings"
# Allow the user to set the variable universally
set -q fish_key_bindings
Expand All @@ -28,76 +28,76 @@ function fish_default_key_bindings -d "Default (Emacs-like) key bindings for fis
or return # protect against invalid $argv

# This is the default binding, i.e. the one used if no other binding matches
bind $argv "" self-insert
bind --preset $argv "" self-insert
or exit # protect against invalid $argv

bind $argv \n execute
bind $argv \r execute
bind --preset $argv \n execute
bind --preset $argv \r execute

bind $argv \ck kill-line
bind --preset $argv \ck kill-line

bind $argv \eOC forward-char
bind $argv \eOD backward-char
bind $argv \e\[C forward-char
bind $argv \e\[D backward-char
bind $argv -k right forward-char
bind $argv -k left backward-char
bind --preset $argv \eOC forward-char
bind --preset $argv \eOD backward-char
bind --preset $argv \e\[C forward-char
bind --preset $argv \e\[D backward-char
bind --preset $argv -k right forward-char
bind --preset $argv -k left backward-char

bind $argv -k dc delete-char
bind $argv -k backspace backward-delete-char
bind $argv \x7f backward-delete-char
bind --preset $argv -k dc delete-char
bind --preset $argv -k backspace backward-delete-char
bind --preset $argv \x7f backward-delete-char

# for PuTTY
# https://github.com/fish-shell/fish-shell/issues/180
bind $argv \e\[1~ beginning-of-line
bind $argv \e\[3~ delete-char
bind $argv \e\[4~ end-of-line
bind --preset $argv \e\[1~ beginning-of-line
bind --preset $argv \e\[3~ delete-char
bind --preset $argv \e\[4~ end-of-line

# OS X SnowLeopard doesn't have these keys. Don't show an annoying error message.
bind $argv -k home beginning-of-line 2>/dev/null
bind $argv -k end end-of-line 2>/dev/null
bind $argv \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete
bind --preset $argv -k home beginning-of-line 2>/dev/null
bind --preset $argv -k end end-of-line 2>/dev/null
bind --preset $argv \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete

bind $argv \ca beginning-of-line
bind $argv \ce end-of-line
bind $argv \ch backward-delete-char
bind $argv \cp up-or-search
bind $argv \cn down-or-search
bind $argv \cf forward-char
bind $argv \cb backward-char
bind $argv \ct transpose-chars
bind $argv \et transpose-words
bind $argv \eu upcase-word
bind --preset $argv \ca beginning-of-line
bind --preset $argv \ce end-of-line
bind --preset $argv \ch backward-delete-char
bind --preset $argv \cp up-or-search
bind --preset $argv \cn down-or-search
bind --preset $argv \cf forward-char
bind --preset $argv \cb backward-char
bind --preset $argv \ct transpose-chars
bind --preset $argv \et transpose-words
bind --preset $argv \eu upcase-word

# This clashes with __fish_list_current_token
# bind $argv \el downcase-word
bind $argv \ec capitalize-word
# bind --preset $argv \el downcase-word
bind --preset $argv \ec capitalize-word
# One of these is alt+backspace.
bind $argv \e\x7f backward-kill-word
bind $argv \e\b backward-kill-word
bind $argv \eb backward-word
bind $argv \ef forward-word
bind $argv \e\[1\;5C forward-word
bind $argv \e\[1\;5D backward-word
bind $argv \e\< beginning-of-buffer
bind $argv \e\> end-of-buffer
bind --preset $argv \e\x7f backward-kill-word
bind --preset $argv \e\b backward-kill-word
bind --preset $argv \eb backward-word
bind --preset $argv \ef forward-word
bind --preset $argv \e\[1\;5C forward-word
bind --preset $argv \e\[1\;5D backward-word
bind --preset $argv \e\< beginning-of-buffer
bind --preset $argv \e\> end-of-buffer

bind $argv \ed kill-word
bind --preset $argv \ed kill-word

# Ignore some known-bad control sequences
# https://github.com/fish-shell/fish-shell/issues/1917
bind $argv \e\[I 'begin;end'
bind $argv \e\[O 'begin;end'
bind --preset $argv \e\[I 'begin;end'
bind --preset $argv \e\[O 'begin;end'

# term-specific special bindings
switch "$TERM"
case 'rxvt*'
bind $argv \e\[8~ end-of-line
bind $argv \eOc forward-word
bind $argv \eOd backward-word
bind --preset $argv \e\[8~ end-of-line
bind --preset $argv \eOc forward-word
bind --preset $argv \eOd backward-word
case 'xterm-256color'
# Microsoft's conemu uses xterm-256color plus
# the following to tell a console to paste:
bind $argv \e\x20ep fish_clipboard_paste
bind --preset $argv \e\x20ep fish_clipboard_paste
end
end
2 changes: 1 addition & 1 deletion share/functions/fish_hybrid_key_bindings.fish
@@ -1,5 +1,5 @@
function fish_hybrid_key_bindings --description "Vi-style bindings that inherit emacs-style bindings in all modes"
bind --erase --all # clear earlier bindings, if any
bind --erase --all --preset # clear earlier bindings, if any

if test "$fish_key_bindings" != "fish_hybrid_key_bindings"
# Allow the user to set the variable universally
Expand Down

0 comments on commit 5e646b3

Please sign in to comment.