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