Skip to content

Instantly share code, notes, and snippets.

@mathgeniuszach
Last active March 31, 2026 23:18
Show Gist options
  • Select an option

  • Save mathgeniuszach/33d1a8988912a967594e2f42313eefee to your computer and use it in GitHub Desktop.

Select an option

Save mathgeniuszach/33d1a8988912a967594e2f42313eefee to your computer and use it in GitHub Desktop.
# For making the [fish shell](https://fishshell.com) bind properly.
#
# The [`bind`](https://fishshell.com/docs/current/cmds/bind.html) command
# handles nearly all bindings on fish. However, some plugins may want more.
# This will assume the user has no plugins - they are free to rebind their own.
#
# Having [shift selection](https://github.com/fish-shell/fish-shell/issues/8677)
# is incredibly nice. It just needs a couple of functions to test if the user has
# anything selected and to execute on shift+keys (with the kitty protocol)
# Set to 1 if you want pasted content to be automatically selected.
# set SHELL_SELECT_PASTED_CONTENT 1
# Set to 1 if you want copying to clear the selection
# set SHELL_COPY_CLEAR_SELECTION 1
# Set to 1 if you want the cursor to overwrite characters by default (Insert to toggle).
# set SHELL_CURSOR_OVERWRITE_MODE 1
# Check if anything is currently selected.
function _is_selecting
set _sel_start (commandline -B)
set _sel_end (commandline -E)
if test -n "$_sel_start" -o -n "$_sel_end"
return 0
else
return 1
end
end
# Properly handle selection when shift+key is pressed (because fish can do that)
function _handle_selection
if not _is_selecting
commandline --function begin-selection
end
commandline --function $argv
end
# For keys like backspace/delete, it's expected for them to delete the selection,
# and if there is no selection, only then perform their normal action.
function _kill_selection_or
if _is_selecting
commandline --function kill-selection
else
commandline --function $argv
end
end
# Needed as some commands act funky if end-selection is called.
# Namely up-or-search/down-or-search on multiline functions.
function _end_selection_with
if _is_selecting
commandline --function end-selection
end
$argv
end
# For entering a newline instead of submitting the command.
# Used by Shift+Enter and Ctrl+Enter.
function _insert_newline
commandline -i \\n (commandline --search-field >/dev/null && echo --search-field)
end
# Override for pasting so it kills the selection if it exists.
if not type __original_fish_paste &> /dev/null
functions --copy __fish_paste __original_fish_paste
end
function __fish_paste
if _is_selecting
commandline --function kill-selection end-selection
end
# Select pasted content
if test -n "$SHELL_SELECT_PASTED_CONTENT"
commandline --function begin-selection
end
__original_fish_paste $argv
end
# Makes the "insert" key toggle the cursor between overwrite/insert mode.
function _toggle_cursor_overwrite_mode
if test -z "$SHELL_CURSOR_OVERWRITE_MODE"
set -g SHELL_CURSOR_OVERWRITE_MODE 1
else
set -g SHELL_CURSOR_OVERWRITE_MODE
end
end
# For generic characters being typed, conditionally replace either selection or rightmost character.
function _delete_conditional
if _is_selecting
commandline --function kill-selection
else if test "$SHELL_CURSOR_OVERWRITE_MODE" = 1
commandline --function delete-char
end
end
# For conditionally clearing the selection based on environment variable
function _copy_and_maybe_clear
fish_clipboard_copy
if test -n "$SHELL_COPY_CLEAR_SELECTION"
commandline --function end-selection
end
end
bind escape end-selection suppress-autosuggestion or clear-commandline
bind enter execute end-selection
bind shift-enter kill-selection end-selection _insert_newline expand-abbr
bind ctrl-enter kill-selection end-selection _insert_newline expand-abbr
bind tab complete # This tab completes forwards.
bind shift-tab complete-and-search # This is the backwards one, sneakily.
bind insert _toggle_cursor_overwrite_mode
bind ctrl-a end-selection beginning-of-line begin-selection end-of-line # selecting everything
bind ctrl-x fish_clipboard_copy kill-selection end-selection
bind ctrl-c _copy_and_maybe_clear
bind ctrl-v kill-selection end-selection fish_clipboard_paste
bind ctrl-shift-c _copy_and_maybe_clear
bind ctrl-shift-v kill-selection end-selection fish_clipboard_paste
bind ctrl-z undo end-selection
bind ctrl-shift-z redo end-selection
bind ctrl-y redo end-selection
# bind ctrl-f search (does not exist) # Terminal can handle this one
bind ctrl-l clear-screen end-selection
bind ctrl-w exit
bind left backward-char end-selection
bind right forward-char end-selection
bind ctrl-left backward-word end-selection
bind ctrl-right forward-word end-selection
bind alt-left backward-token end-selection
bind alt-right forward-token end-selection
bind ctrl-alt-left beginning-of-line end-selection
bind ctrl-alt-right end-of-line end-selection
bind up '_end_selection_with up-or-search'
bind down '_end_selection_with down-or-search'
bind home beginning-of-line end-selection
bind end end-of-line end-selection
bind ctrl-home beginning-of-buffer end-selection
bind ctrl-end end-of-buffer end-selection
# Handle selections
bind shift-left '_handle_selection backward-char'
bind shift-right '_handle_selection forward-char'
bind ctrl-shift-left '_handle_selection backward-word'
bind ctrl-shift-right '_handle_selection forward-word'
bind alt-shift-left '_handle_selection backward-token'
bind alt-shift-right '_handle_selection forward-token'
bind ctrl-alt-shift-left '_handle_selection beginning-of-line'
bind ctrl-alt-shift-right '_handle_selection end-of-line'
bind shift-up '_handle_selection up-line'
bind shift-down '_handle_selection down-line'
bind shift-home '_handle_selection beginning-of-line'
bind shift-end '_handle_selection end-of-line'
bind ctrl-shift-home '_handle_selection beginning-of-buffer'
bind ctrl-shift-end '_handle_selection end-of-buffer'
bind backspace '_kill_selection_or backward-delete-char' end-selection
bind delete '_kill_selection_or delete-char' end-selection
bind ctrl-backspace '_kill_selection_or backward-kill-word' end-selection
bind ctrl-delete '_kill_selection_or kill-word' end-selection
bind alt-backspace '_kill_selection_or backward-kill-token' end-selection
bind alt-delete '_kill_selection_or kill-token' end-selection
bind ctrl-shift-backspace clear-screen clear-commandline end-selection
bind ctrl-shift-delete clear-screen clear-commandline end-selection
# bind shift-space begin-selection # not needed as shift selection works
bind '' _delete_conditional end-selection self-insert
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment