Table of contents
- Intro
- fish_user_key_bindings
- down-or-nextd-or-forward-word
- up-or-prevd-or-backward-word
- toggle-complete
- More advanced usage
- Running external tools
- Using fzf with keybinds
Intro
Wanting to extend the keybinding functions of the fish shell first came to me
when I was to add use cases to my <C-k>
and <C-j>
keys. In my keybind
functions I initially had <C-k>
and <C-j>
bound to the functions
prevd-or-backward-word
and nextd-or-forward-word
. The behviour I provided to
these functions was being able to navigate the completion-list/pager up and down
as well as the default functions mentioned already. In this post, we will delve
into how I did this first by reviewing these functions, and then working our way
into more advanced interactive functions to bind keys to.
fish_user_key_bindings
Here, is where I’ll be placing each respective function I describe below. This
function will need to be defined in the $fish_autoloaded_functions
path, and
will also need to be called in the ~/.config/fish/config.fish
. In the
future I might create an actual fisher plugin to make these features more
accessible.
~/.config/fish/functions/fish_user_key_bindings.fish
function fish_user_key_bindings
bind \cj 'down-or-nextd-or-forward-word'
bind \ck 'up-or-prevd-or-backward-word'
#...
end
~/.config/fish/config.fish
# ...
# call the function so that keybinds are bound when the shell process starts
fish_user_key_bindings
# ...
down-or-nextd-or-forward-word
This will move down the pager if it visible in the current command line. If the
pager is not visible, then it handle the nextd-or-forward-word
case.
function down-or-nextd-or-forward-word
if not commandline --paging-mode; and not commandline --search-mode
commandline -f nextd-or-forward-word
return
else
commandline -f down-line
return
end
end
up-or-prevd-or-backward-word
This function will interactively move down through the pager if it has been toggle visible for the current command. If the pager is not visible, then it calls prevd-or-backward-word.
function up-or-prevd-or-backward-word -d "if in completion mode(pager), then move up, otherwise, prevd-or-forward-word"
if not commandline --paging-mode; and not commandline --search-mode
commandline -f prevd-or-backward-word
return
else
commandline -f up-line
return
end
end
toggle-complete
This function will interactively handle opening and closing the pager to show
completions for the current commandline. In my config I have the following
function bound in fish_user_key_bindings as: bind -k nul toggle-auto-complete
. On every keyboard I’ve interacted with, the nul keysequence is sent for Control+Space
function toggle-complete
if commandline --paging-mode; or commandline --search-mode
commandline -f suppress-autosuggestion
commandline -f accept-autosuggestion
else
commandline -f complete
end
end
More advanced usage
With the previously introduced functions, we see some nice functionality added to the fish-shell experience. The below functions are more advanced, and require some of the following tools:
Running external tools
For the commands: ranger
, alacritty
, and lazy-git
I simply bind them to
keys to launch new processes using them in the shell. Since these commands break
the interactive prompt, we have to repaint the commandline after the sub-process
exits. This is done by following the keybind with commandline -f repaint
.
Here’s a simple snippet showing possible bindings for these functions in the fish_user_key_bindings file.
bind \cR 'ranger; commandline -f repaint'
bind \cG 'lazygit; commandline -f repaint'
bind \cT 'alacritty --working-directory "$PWD" &;disown $last_pid; commandline -f repaint'
Using fzf with keybinds
Here I will outline two useful keybinds, I use regularly. First I will show
fzf-history-or-copy-to-clipboard
and next I will show fzf-search-or-toggle-complete
.
fzf-history-or-copy-to-clipboard
If there is text in the current commandline, then this function yanks (places it in the system clipboard) & clears the command line. If the command line is empty it pipes the history list into fzf and allows you to select a previous command to copy to the clipboard.
function fzf-history-or-copy-to-clipboard -d "copy to clipboard from history or current cmd"
set -l current (commandline -c); # to test this line run 'bind \cy "commandline -r (commandline -c)"'
if test -z "$current"
set current (__history_fzf);
end
commandline $current;and fish_clipboard_copy;
commandline -r ""; and commandline -f repaint;
end
function __history_fzf
set -l res (history | fzf --no-sort)
echo $res;
end