Yank to clipboard in fish shell's vi mode
Avg. 3 minute(s) of readingI 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.
The problem
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. yy
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.
The solution
Fish has a variable that exposes the content of the killring: $fish_killring
. This is a list using 1-based indexing (unlike many programming languages). The latest copied element is always at index 1, e.g. echo $fish_killring[1]
. This makes it easy to write a function to yank to the clipboard:
1# ~/.config/fish/functions/yank_to_clipboard.fish 2 3function yank_to_clipboard -d "Insert latest killring entry into the system clipboard" 4 printf "%s" "$fish_killring[1]" | fish_clipboard_copy 5end
Afterwards, we just need to adjust the preset vi mode keybindings. In my system, these preset keybindings are stored in /usr/share/fish/functions/fish_vi_key_bindings.fish
. I've taken the ones that deal with yanking and pasting, and tweaked them by calling yank_to_clipboard
before all yanks and always pasting from the system's clipboard:
1# ~/.config/fish/functions/fish_user_key_bindings.fish 2 3function fish_user_key_bindings 4 # make vi mode yanks copy to clipboard 5 bind yy kill-whole-line yank_to_clipboard yank 6 bind Y kill-whole-line yank_to_clipboard yank 7 bind y,\$ kill-line yank_to_clipboard yank 8 bind y,\^ backward-kill-line yank_to_clipboard yank 9 bind y,0 backward-kill-line yank_to_clipboard yank 10 bind y,w kill-word yank_to_clipboard yank 11 bind y,W kill-bigword yank_to_clipboard yank 12 bind y,i,w forward-single-char forward-single-char backward-word kill-word yank_to_clipboard yank 13 bind y,i,W forward-single-char forward-single-char backward-bigword kill-bigword yank_to_clipboard yank 14 bind y,a,w forward-single-char forward-single-char backward-word kill-word yank_to_clipboard yank 15 bind y,a,W forward-single-char forward-single-char backward-bigword kill-bigword yank_to_clipboard yank 16 bind y,e kill-word yank_to_clipboard yank 17 bind y,E kill-bigword yank_to_clipboard yank 18 bind y,b backward-kill-word yank_to_clipboard yank 19 bind y,B backward-kill-bigword yank_to_clipboard yank 20 bind y,g,e backward-kill-word yank_to_clipboard yank 21 bind y,g,E backward-kill-bigword yank_to_clipboard yank 22 bind y,f begin-selection forward-jump kill-selection yank_to_clipboard yank end-selection 23 bind y,t begin-selection forward-jump-till kill-selection yank_to_clipboard yank end-selection 24 bind y,F begin-selection backward-jump kill-selection yank_to_clipboard yank end-selection 25 bind y,T begin-selection backward-jump-till kill-selection yank_to_clipboard yank end-selection 26 bind y,h backward-char begin-selection kill-selection yank_to_clipboard yank end-selection 27 bind y,l begin-selection kill-selection yank_to_clipboard yank end-selection 28 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 29 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 30 bind y,i backward-jump-till and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank_to_clipboard yank end-selection 31 bind y,a backward-jump and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank_to_clipboard yank end-selection 32 bind -M visual -m default y kill-selection yank_to_clipboard yank end-selection repaint-mode 33 34 # use system clipboard for vi mode pastes 35 bind -s p 'set -g fish_cursor_end_mode exclusive' forward-char 'set -g fish_cursor_end_mode inclusive' fish_clipboard_paste 36 bind -s P fish_clipboard_paste 37end
Fish will load these functions when necessary, so you just need to put them in the right place (~/.config/fish/functions
).
Conclusion
After I found out about the $fish_killring
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