Custom Vim Bindings in tmux 2.4
tmux 2.4 made a significant change to key bindings. Here is how to support custom keybindings for versions before and after tmux 2.4
Changes in tmux 2.4 ¶
tmux continues to move on apace which is great news for the project. Since version 2 there have been several breaking changes to configuration options. This is fine if you run tmux on a machine that you maintain as it is easy to keep tmux configuration in sync with the the version on the machine. If, like me, you favour wrapping up your configuration in a dotfiles repository this poses a challenge in supporting multiple versions of tmux with differing configuration options.
Tmux & Nearly Mouseless Workflow ¶
tmux supports me achieving a nearly mouseless workflow with the copy and paste functionality being a big part of that. Jason Ryan wrote about how to achieve this. I’m a Vim user and here is the configuration I used.
bind-key Escape copy-mode
bind-key -t vi-copy Escape cancel
bind-key p paste-buffer
bind-key -t vi-copy v begin-selection
bind-key -t vi-copy V select-line
bind-key -t vi-copy r rectangle-toggle
bind -t vi-copy y copy-pipe "xclip -in -selection clipboard"
The copy-pipe
option supports pasting into screens outside of tmux by copying
to the system clipboard. Coupled with dwm this supports changing screens
and moving data between contexts without having to touch the mouse.
New copy mode key bindings ¶
This commit made a fundamental change to how keybindings work. After some tinkering my configuration now looks like this.
bind-key -T copy-mode-vi 'v' send -X begin-selection
bind-key -T copy-mode-vi 'V' send -X select-line
bind-key -T copy-mode-vi 'r' send -X rectangle-toggle
bind-key -T copy-mode-vi 'y' send -X copy-pipe-and-cancel "xclip -in -selection clipboard"
The options available are yet to be fully documented but the default
bindings are sane and the addition of copy-pipe-and-cancel
is fantastic!
The problem is that for some machines that I use I am able to upgrade tmux. So how to support multiple configuration options?
Enter if-shell ¶
A couple of StackOverflow posts led me to if-shell
that allows
different configurations to be declared based on the tmux version. My
configurations for Vim bindings in copy mode now looks like this.
run-shell "tmux setenv -g TMUX_VERSION $(tmux -V | cut -c 6-)"
if-shell -b '[ "$(echo "$TMUX_VERSION < 2.4" | bc)" = 1 ]' \
"bind-key Escape copy-mode; \
bind-key -t vi-copy Escape cancel; \
bind-key p paste-buffer; \
bind-key -t vi-copy v begin-selection; \
bind-key -t vi-copy V select-line; \
bind-key -t vi-copy r rectangle-toggle; \
bind -t vi-copy y copy-pipe 'xclip -in -selection clipboard'"
if-shell -b '[ "$(echo "$TMUX_VERSION >= 2.4" | bc)" = 1 ]' \
"bind-key -T copy-mode-vi 'v' send -X begin-selection; \
bind-key -T copy-mode-vi 'V' send -X select-line; \
bind-key -T copy-mode-vi 'r' send -X rectangle-toggle; \
bind-key -T copy-mode-vi 'y' send -X copy-pipe-and-cancel 'xclip -in -selection clipboard'"
This checks the tmux version and applies configuration accordingly. If you are interested in what has changed recently the CHANGES documents this.
Conclusion ¶
tmux continues to be a core part of my daily toolkit. Copying and pasting
without touching the mouse and being able to return to sessions are the two
features that keep me using tmux. Otherwise I would just use fg
and bg
. It
is great to see the project being actively developed and now I have a way to
handle breaking changes to the configuration gracefully.
Tags
Can you help make this article better? You can edit it here and send me a pull request.
See Also
-
Using template files in Vim
Vim templates or skeletons, allow you to specify a template to be used for new files with a certain extension. -
Vim eighteen months on
I switched to Vim for editing text about 18 months ago. Here's an overview of my experience. -
Vim: So long Pathogen, hello native package loading
Vim 8 added a native way to load third-party packages. This means, for me at least, there is no longer any need to use a third party plugin helper like Pathogen.