[38;5;244m┌─[0m [38;5;40mroot@joaocosta:~#[0m [38;5;245mcat posts/17.md[0m [38;5;244m───────────────────────────────────────────[0m

[38;5;40m#[0m [1mYank to clipboard in fish shell's vi mode[0m
[38;5;245mpublished 2025-09-30 · 3 min read · https://joaocosta.dev/blog/17[0m

I don't really use/like vim's killring, so I usually just send all yanks
(copies) to the system's clipboard (and paste from it as well). Vi mode in fish
shell does not support using the system clipboard, so I wrote a small config for
that.

[38;5;38m##[0m [1mThe problem[0m

When using vi mode in fish shell, you have access to vim-like normal, visual,
etc. modes. When you use yank and paste vim keybindings, e.g. [38;5;38myy[0m in normal mode
(yank line), the contents are inserted/pulled from the killring: basically a
list of the things you've yanked that's only accessible within the current fish
shell prompt. It's not even accessible from cli programs you open in that
session. I want these keybindings to use the system clipboard instead.

[38;5;38m##[0m [1mThe solution[0m

Fish has a variable that exposes the content of the killring: [38;5;38m$fish_killring[0m.
This is a list using 1-based indexing (unlike many programming languages). The
latest copied element is always at index 1, e.g. [38;5;38mecho $fish_killring[1][0m. This
makes it easy to write a function to yank to the clipboard:

[38;5;244m┄──────────────────────────────────────────────────────────────────────── fish [0m
[38;5;245m│[0m # ~/.config/fish/functions/yank_to_clipboard.fish
[38;5;245m│[0m 
[38;5;245m│[0m function yank_to_clipboard -d "Insert latest killring entry into the system clipboard"
[38;5;245m│[0m     printf "%s" "$fish_killring[1]" | fish_clipboard_copy
[38;5;245m│[0m end
[38;5;244m┄──────────────────────────────────────────────────────────────────────────────[0m

Afterwards, we just need to adjust the preset vi mode keybindings. In my system,
these preset keybindings are stored in
[38;5;38m/usr/share/fish/functions/fish_vi_key_bindings.fish[0m. I've taken the ones that
deal with yanking and pasting, and tweaked them by calling [38;5;38myank_to_clipboard[0m
before all yanks and always pasting from the system's clipboard:

[38;5;244m┄──────────────────────────────────────────────────────────────────────── fish [0m
[38;5;245m│[0m # ~/.config/fish/functions/fish_user_key_bindings.fish
[38;5;245m│[0m 
[38;5;245m│[0m function fish_user_key_bindings
[38;5;245m│[0m     # make vi mode yanks copy to clipboard
[38;5;245m│[0m     bind yy kill-whole-line yank_to_clipboard yank
[38;5;245m│[0m     bind Y kill-whole-line yank_to_clipboard yank
[38;5;245m│[0m     bind y,\$ kill-line yank_to_clipboard yank
[38;5;245m│[0m     bind y,\^ backward-kill-line yank_to_clipboard yank
[38;5;245m│[0m     bind y,0 backward-kill-line yank_to_clipboard yank
[38;5;245m│[0m     bind y,w kill-word yank_to_clipboard yank
[38;5;245m│[0m     bind y,W kill-bigword yank_to_clipboard yank
[38;5;245m│[0m     bind y,i,w forward-single-char forward-single-char backward-word kill-word yank_to_clipboard yank
[38;5;245m│[0m     bind y,i,W forward-single-char forward-single-char backward-bigword kill-bigword yank_to_clipboard yank
[38;5;245m│[0m     bind y,a,w forward-single-char forward-single-char backward-word kill-word yank_to_clipboard yank
[38;5;245m│[0m     bind y,a,W forward-single-char forward-single-char backward-bigword kill-bigword yank_to_clipboard yank
[38;5;245m│[0m     bind y,e kill-word yank_to_clipboard yank
[38;5;245m│[0m     bind y,E kill-bigword yank_to_clipboard yank
[38;5;245m│[0m     bind y,b backward-kill-word yank_to_clipboard yank
[38;5;245m│[0m     bind y,B backward-kill-bigword yank_to_clipboard yank
[38;5;245m│[0m     bind y,g,e backward-kill-word yank_to_clipboard yank
[38;5;245m│[0m     bind y,g,E backward-kill-bigword yank_to_clipboard yank
[38;5;245m│[0m     bind y,f begin-selection forward-jump kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind y,t begin-selection forward-jump-till kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind y,F begin-selection backward-jump kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind y,T begin-selection backward-jump-till kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind y,h backward-char begin-selection kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind y,l begin-selection kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind y,i,b jump-till-matching-bracket and jump-till-matching-bracket and begin-selection jump-till-matching-bracket kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind y,a,b jump-to-matching-bracket and jump-to-matching-bracket and begin-selection jump-to-matching-bracket kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind y,i backward-jump-till and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind y,a backward-jump and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank_to_clipboard yank end-selection
[38;5;245m│[0m     bind -M visual -m default y kill-selection yank_to_clipboard yank end-selection repaint-mode
[38;5;245m│[0m 
[38;5;245m│[0m 	# use system clipboard for vi mode pastes
[38;5;245m│[0m     bind -s p 'set -g fish_cursor_end_mode exclusive' forward-char 'set -g fish_cursor_end_mode inclusive' fish_clipboard_paste
[38;5;245m│[0m     bind -s P fish_clipboard_paste
[38;5;245m│[0m end
[38;5;244m┄──────────────────────────────────────────────────────────────────────────────[0m

Fish will load these functions when necessary, so you just need to put them in
the right place ([38;5;38m~/.config/fish/functions[0m).

[38;5;38m##[0m [1mConclusion[0m

After I found out about the [38;5;38m$fish_killring[0m variable, it was quite easy to fix my
problem. Remember to restart your shell or source your config after making these
changes. Hope you get some use out of it too.

Stay safe :P

[38;5;244m└─[0m [38;5;40m→[0m view online: [38;5;40mhttps://joaocosta.dev/blog/17[0m
