Last active
September 3, 2022 22:53
-
-
Save sshilovsky/7a66f4381dd3b2a02b386a333d174d19 to your computer and use it in GitHub Desktop.
Bare minimum helix mode for fish
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 1. Put these files in ~/.config/fish/functions/ | |
# 2. run fish_helix_key_bindings | |
# To switch back, run fish_default_key_bindings |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function fish_default_mode_prompt --description "Display vi/helix prompt mode" | |
# Do nothing if not in vi mode | |
if test "$fish_key_bindings" = fish_vi_key_bindings | |
or test "$fish_key_bindings" = fish_helix_key_bindings | |
or test "$fish_key_bindings" = fish_hybrid_key_bindings | |
switch $fish_bind_mode | |
case default | |
set_color --bold red | |
echo '[N]' | |
case insert | |
set_color --bold green | |
echo '[I]' | |
case replace_one | |
set_color --bold green | |
echo '[R]' | |
case replace | |
set_color --bold cyan | |
echo '[R]' | |
case visual | |
set_color --bold magenta | |
echo '[V]' | |
end | |
set_color normal | |
echo -n ' ' | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function fish_helix_key_bindings --description 'helix-like key bindings for fish' | |
if contains -- -h $argv | |
or contains -- --help $argv | |
echo "Sorry but this function doesn't support -h or --help" | |
return 1 | |
end | |
# Erase all bindings if not explicitly requested otherwise to | |
# allow for hybrid bindings. | |
# This needs to be checked here because if we are called again | |
# via the variable handler the argument will be gone. | |
set -l rebind true | |
if test "$argv[1]" = --no-erase | |
set rebind false | |
set -e argv[1] | |
else | |
bind --erase --all --preset # clear earlier bindings, if any | |
end | |
# Allow just calling this function to correctly set the bindings. | |
# Because it's a rather discoverable name, users will execute it | |
# and without this would then have subtly broken bindings. | |
if test "$fish_key_bindings" != fish_helix_key_bindings | |
and test "$rebind" = true | |
# Allow the user to set the variable universally. | |
set -q fish_key_bindings | |
or set -g fish_key_bindings | |
# This triggers the handler, which calls us again and ensures the user_key_bindings | |
# are executed. | |
set fish_key_bindings fish_helix_key_bindings | |
return | |
end | |
set -l init_mode insert | |
if contains -- $argv[1] insert default visual | |
set init_mode $argv[1] | |
else if set -q argv[1] | |
# We should still go on so the bindings still get set. | |
echo "Unknown argument $argv" >&2 | |
end | |
# Inherit shared key bindings. | |
# Do this first so helix-bindings win over default. | |
for mode in insert default visual | |
__fish_shared_key_bindings -s -M $mode | |
end | |
bind -s --preset -M insert \r execute | |
bind -s --preset -M insert \n execute | |
bind -s --preset -M insert "" self-insert | |
# Space and other command terminators expand abbrs _and_ inserts itself. | |
bind -s --preset -M insert " " self-insert expand-abbr | |
bind -s --preset -M insert ";" self-insert expand-abbr | |
bind -s --preset -M insert "|" self-insert expand-abbr | |
bind -s --preset -M insert "&" self-insert expand-abbr | |
bind -s --preset -M insert "^" self-insert expand-abbr | |
bind -s --preset -M insert ">" self-insert expand-abbr | |
bind -s --preset -M insert "<" self-insert expand-abbr | |
# Closing a command substitution expands abbreviations | |
bind -s --preset -M insert ")" self-insert expand-abbr | |
# Ctrl-space inserts space without expanding abbrs | |
bind -s --preset -M insert -k nul 'commandline -i " "' | |
# Switching to insert mode | |
for mode in default visual | |
bind -s --preset -M $mode -m insert \cc end-selection cancel-commandline repaint-mode | |
bind -s --preset -M $mode -m insert \n end-selection execute | |
bind -s --preset -M $mode -m insert \r end-selection execute | |
bind -s --preset -M $mode -m insert o end-selection insert-line-under repaint-mode | |
bind -s --preset -M $mode -m insert O end-selection insert-line-over repaint-mode | |
# FIXME handle selection properly for the following commands (at the command, and during editing): | |
bind -s --preset -M $mode -m insert i end-selection repaint-mode | |
bind -s --preset -M $mode -m insert I end-selection beginning-of-line repaint-mode | |
bind -s --preset -M $mode -m insert a end-selection forward-single-char repaint-mode | |
bind -s --preset -M $mode -m insert A end-selection end-of-line repaint-mode | |
end | |
# Switching from insert mode | |
# Note if we are paging, we want to stay in insert mode | |
# See #2871 | |
bind -s --preset -M insert \e "if commandline -P; commandline -f cancel; else; set fish_bind_mode default; commandline -f begin-selection repaint-mode; end" | |
# Switching between normal and visual mode | |
bind -s --preset -M default -m visual v repaint-mode | |
for key in v \e | |
bind -s --preset -M visual -m default $key repaint-mode | |
end | |
# FIXME count commands | |
# Motion and actions in normal/visual mode | |
for mode in default visual | |
if test $mode = default | |
set -f n_begin_selection "begin-selection" # only begin-selection if current mode is Normal | |
else | |
set -f n_begin_selection "" | |
end | |
bind -s --preset -M $mode h backward-char $n_begin_selection | |
bind -s --preset -M $mode l forward-char $n_begin_selection | |
# FIXME arrows | |
bind -s --preset -M $mode gh beginning-of-line $n_begin_selection | |
bind -s --preset -M $mode gl end-of-line $n_begin_selection | |
bind -s --preset -M $mode gg beginning-of-buffer $n_begin_selection | |
bind -s --preset -M $mode ge end-of-buffer beginning-of-line $n_begin_selection | |
# FIXME home/end | |
bind -s --preset -M $mode u undo begin-selection | |
bind -s --preset -M $mode U redo begin-selection | |
# FIXME fix w/e/b behavior in normal mode (needs cpp implementation) | |
bind -s --preset -M $mode w $n_begin_selection forward-word | |
bind -s --preset -M $mode W $n_begin_selection forward-bigword | |
bind -s --preset -M $mode b backward-char $n_begin_selection backward-word | |
bind -s --preset -M $mode B backward-char $n_begin_selection backward-bigword | |
bind -s --preset -M $mode e forward-single-char $n_begin_selection forward-word backward-char | |
bind -s --preset -M $mode E forward-single-char $n_begin_selection forward-bigword backward-char | |
bind -s --preset -M $mode f $n_begin_selection forward-jump | |
bind -s --preset -M $mode F $n_begin_selection backward-jump | |
bind -s --preset -M $mode t $n_begin_selection forward-single-char forward-jump-till | |
bind -s --preset -M $mode T $n_begin_selection backward-char backward-jump-till | |
# FIXME alt-. doesn't work with t/T | |
bind -s --preset -M $mode \e. $n_begin_selection repeat-jump | |
bind -s --preset -M $mode -m replace_one r repaint-mode | |
# FIXME ! | |
# FIXME registers | |
# FIXME selection and cursor behavior | |
bind -s --preset -M $mode y fish_clipboard_copy | |
bind -s --preset -M $mode P fish_clipboard_paste | |
bind -s --preset -M $mode p "commandline -f forward-single-char begin-selection ; fish_clipboard_paste" | |
bind -s --preset -M $mode Q yank-pop | |
bind -s --preset -M $mode R kill-selection begin-selection yank-pop yank | |
# FIXME keep selection | |
bind -s --preset -M $mode ~ togglecase-selection | |
# FIXME ` and \e` | |
# FIXME . | |
# FIXME < and > | |
# FIXME = | |
bind -s --preset -M $mode -m default d kill-selection begin-selection $v_repaint_mode | |
bind -s --preset -M $mode -m insert c kill-selection end-selection repaint-mode | |
# FIXME \ed \ec | |
# FIXME \ca \cx | |
# FIXME Qq | |
## Shell | |
# FIXME | |
## Selection manipulation | |
# FIXME & _ | |
bind -s --preset -M $mode \; begin-selection | |
bind -s --preset -M $mode \e\; swap-selection-start-stop | |
# FIXME \e: | |
# FIXME % | |
# FIXME x X \ex | |
# FIXME J | |
# FIXME \cc | |
## Search | |
# FIXME | |
## FIXME minor modes: g, m, space | |
## FIXME [ and ] motions | |
end | |
# FIXME should replace the whole selection | |
# FIXME should be able to go back to visual mode | |
bind -s --preset -M replace_one -m default '' delete-char self-insert backward-char repaint-mode | |
bind -s --preset -M replace_one -m default \r 'commandline -f delete-char; commandline -i \n; commandline -f backward-char; commandline -f repaint-mode' | |
bind -s --preset -M replace_one -m default \e cancel repaint-mode | |
bind -s --preset -M default k up-or-search | |
bind -s --preset -M default j down-or-search | |
bind -s --preset -M visual k up-line | |
bind -s --preset -M visual j down-line | |
# FIXME arrows | |
## FIXME Insert mode keys | |
## Old config from vi: | |
# Vi moves the cursor back if, after deleting, it is at EOL. | |
# To emulate that, move forward, then backward, which will be a NOP | |
# if there is something to move forward to. | |
bind -s --preset -M insert -k dc delete-char forward-single-char backward-char | |
bind -s --preset -M default -k dc delete-char forward-single-char backward-char | |
# Backspace deletes a char in insert mode, but not in normal/default mode. | |
bind -s --preset -M insert -k backspace backward-delete-char | |
bind -s --preset -M default -k backspace backward-char | |
bind -s --preset -M insert \ch backward-delete-char | |
bind -s --preset -M default \ch backward-char | |
bind -s --preset -M insert \x7f backward-delete-char | |
bind -s --preset -M default \x7f backward-char | |
bind -s --preset -M insert -k sdc backward-delete-char # shifted delete | |
bind -s --preset -M default -k sdc backward-delete-char # shifted delete | |
# bind -s --preset '~' togglecase-char forward-single-char | |
# bind -s --preset gu downcase-word | |
# bind -s --preset gU upcase-word | |
# | |
# bind -s --preset J end-of-line delete-char | |
# bind -s --preset K 'man (commandline -t) 2>/dev/null; or echo -n \a' | |
# | |
# same vim 'pasting' note as upper | |
bind -s --preset '"*p' forward-char "commandline -i ( xsel -p; echo )[1]" | |
bind -s --preset '"*P' "commandline -i ( xsel -p; echo )[1]" | |
# | |
# visual mode | |
# | |
# bind -s --preset -M visual -m insert c kill-selection end-selection repaint-mode | |
# bind -s --preset -M visual -m insert s kill-selection end-selection repaint-mode | |
bind -s --preset -M visual -m default '"*y' "fish_clipboard_copy; commandline -f end-selection repaint-mode" | |
bind -s --preset -M visual -m default '~' togglecase-selection end-selection repaint-mode | |
# Set the cursor shape | |
# After executing once, this will have defined functions listening for the variable. | |
# Therefore it needs to be before setting fish_bind_mode. | |
# fish_vi_cursor | |
set fish_bind_mode $init_mode | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment