Tmux

Tmux is one of the widest known terminal multiplexers along with screen. I find it useful when I don’t want to bother with panes in my kittyopen in new window terminal.

Be aware this configuration is mostly keybinds.

Setting sane configurations

By default, Tmux does not support all the colours your terminal may support, so we need to tell it to set true colours…

set-option -sa terminal-overrides ",xterm*:Tc"

We can also tell it to enable mouse support. That way, we will be able to click on Tmux elements and scroll in its panes!

set -g mouse on

Finally, I’ll set vi-mode for some sane movements.

set-window-option -g mode-keys vi

Windows and panes configuration

Although I agree in computer science most things should begin with zero, I find it quite weird to see my first window and my first pane to be labelled with it rather than one. So, let’s pull a Lua on Tmux and force it to begin with 1 instead of 0.

set -g base-index 1
set -g pane-base-index 1
set-window-option -g pane-base-index 1
set-option -g renumber-windows on

Plugins!

Using TPMopen in new window, we can use plugins in Tmux! The way I installed it is very simple:

mkdir -p ~/.config/tmux/
git clone https://github.com/tmux-plugins/tpm.git ~/.config/tmux/tpm

Here’s a list of the plugins that I use.

PluginWhy
tpmTPM itself
tmux-sensibleBetter defaults I can’t be bothered to change myself
tmux-yankBetter copy/pasting
tmux-prefix-highlightTell me which prefix I’m using
tmux-resurrectPersist tmux sessions across system restarts
nordtheme/tmuxNord theme for Tmux!
(mapconcat (lambda (plugin)
             (format "set -g @plugin '%s'"
                     (if (string-match-p (quote "/") plugin)
                         plugin
                       (concat "tmux-plugins/" plugin))))
           plugins
           "\n")

Let’s run TPM right after that.

run '~/.config/tmux/tpm/tpm'

For restoring processes with tmux-resurrect, we must add additional programs in the @resurrect-processes variable. These are:

  • "~ncmpcpp -q"
  • btop
  • ssh
set -g @resurrect-processes '"~ncmpcpp -q" btop ssh'

Keybindings

Firstly, I don’t like prefixing all of my keybindings with C-b, that’s what I use in insert-mode in Emacs to make the cursor go back. So instead, let’s set meta with space as my prefix.

unbind C-b
set -g prefix M-Space
bind M-Space send-prefix

Now, I will only add few keybindings on the root prefix that actually do something immediately, I will mostly add keybindings that will lead to other prefixes; I prefer by far to have keychords that are a bit lengthy and mnemonic than some obscure “ C-M-& is for doing this and that”.

KeybindingCommandPrefix to go to
«select-window -p
»select-window -n
Tabwindows
wpane
ycopy-mode

Note I am using the key w to access the pane prefix because of how used to Emacs I am, and in Emacs terminology panes are windows while tmux windows would be tabs.

bind-key -T prefix « select-window -p
bind-key -T prefix » select-window -n
bind-key -T prefix Tab switch-client -T windows
bind-key -T prefix w switch-client -T pane
bind-key -T prefix y switch-client -T copy-mode

Panes

As you will see not only here but also lower, I am not using the usual hjkl to navigate around since I am using the bépoopen in new window layout. I use instead the ctsr keys.

Below are the keybindings living in the pane prefix. Note that calls to split-window have a -c "#{pane_current_path}" argument so new panes open in the same directory as the directory I am currently in.

KeybindingCommandPrefix to go to
/split-window -h -c “#{pane-current_path}”
-split-window -v -c “#{pane-current_path}”
cselect-pane -L
tselect-pane -D
sselect-pane -U
rselect-pane -R
fresize-pane -Z
.pane-resize
bind-key -T pane / split-window -h -c "#{pane-current_path}"
bind-key -T pane - split-window -v -c "#{pane-current_path}"
bind-key -T pane c select-pane -L
bind-key -T pane t select-pane -D
bind-key -T pane s select-pane -U
bind-key -T pane r select-pane -R
bind-key -T pane f resize-pane -Z
bind-key -T pane . switch-client -T pane-resize

When it comes to resizing the panes, the keybindings are in their own prefix referenced above: pane-resize. All keybindings will lead to the same prefix again, which enables the user to type for instance M-Space w . r r r r r in order to call repetitively resize-pane -R 5. Hitting any key that is not part of the current prefix will get us out of it.

KeybindingCommandPrefix to go to
cresize-pane -L 5pane-resize
tresize-pane -D 5pane-resize
sresize-pane -U 5pane-resize
rresize-pane -R 5pane-resize
Cresize-pane -Lpane-resize
Tresize-pane -Dpane-resize
Sresize-pane -Upane-resize
Rresize-pane -Rpane-resize
bind-key -T pane-resize c resize-pane -L 5\; switch-client -T pane-resize
bind-key -T pane-resize t resize-pane -D 5\; switch-client -T pane-resize
bind-key -T pane-resize s resize-pane -U 5\; switch-client -T pane-resize
bind-key -T pane-resize r resize-pane -R 5\; switch-client -T pane-resize
bind-key -T pane-resize C resize-pane -L\; switch-client -T pane-resize
bind-key -T pane-resize T resize-pane -D\; switch-client -T pane-resize
bind-key -T pane-resize S resize-pane -U\; switch-client -T pane-resize
bind-key -T pane-resize R resize-pane -R\; switch-client -T pane-resize

Windows

Since windows are more akin to tabs in Emacs, and I am way more used to it than Tmux, all keybinds are prefixed with a Tab, itself prefixed with the main prefix.

KeybindingCommand
cnew-window
nnext-window
pprevious-window
bind-key -T windows c new-window\; switch-client -T 
bind-key -T windows n next-window\; switch-client -T 
bind-key -T windows p previous-window\; switch-client -T 

In order to access more easily the different windows, I want to be able to type <prefix> TAB <window number>. However, I’m using the bépo layout, numbers are available only when pressing shift. Otherwise, the characters typed are "«»()@+-/* (from 1 to 0).

(let ((keybinds "")
      (keys '("\\\"" "«" "»" "(" ")" "@" "+" "-" "/" "*")))
  (dotimes (i (length keys) keybinds)
    (setq keybinds (string-trim
                    (concat keybinds
                            "\n"
                            (format "bind-key -T windows %s select-window -t :=%d"
                                    (nth i keys)
                                    (1+ i)))))))

Copy in vi mode

Tmux has a nice mode for vim keybindings users: copy-mode-vi which allows moving the cursor around in the pane, select some stuff, and copy it. But first, I need to unbind some keys:

unbind -T copy-mode-vi H
unbind -T copy-mode-vi J
unbind -T copy-mode-vi K
unbind -T copy-mode-vi L
unbind -T copy-mode-vi h
unbind -T copy-mode-vi j
unbind -T copy-mode-vi k
unbind -T copy-mode-vi l
KeybindingCommand
vsend-keys -X begin-selection
C-vsend-keys -X rectangle-toggle
ysend-keys -X copy-selection-and-cancel
Csend-keys -X top-line
Jsend-keys -X jump-to-backward
Ssend-keys -X scroll-up
Rsend-keys -X bottom-line
Tsend-keys -X scroll-down
csend-keys -X cursor-left
tsend-keys -X cursor-down
ssend-keys -X cursor-up
rsend-keys -X cursor-right
bind-key -T copy-mode-vi v send-keys -X begin-selection\; switch-client -T 
bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle\; switch-client -T 
bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel\; switch-client -T 
bind-key -T copy-mode-vi C send-keys -X top-line\; switch-client -T 
bind-key -T copy-mode-vi J send-keys -X jump-to-backward\; switch-client -T 
bind-key -T copy-mode-vi S send-keys -X scroll-up\; switch-client -T 
bind-key -T copy-mode-vi R send-keys -X bottom-line\; switch-client -T 
bind-key -T copy-mode-vi T send-keys -X scroll-down\; switch-client -T 
bind-key -T copy-mode-vi c send-keys -X cursor-left\; switch-client -T 
bind-key -T copy-mode-vi t send-keys -X cursor-down\; switch-client -T 
bind-key -T copy-mode-vi s send-keys -X cursor-up\; switch-client -T 
bind-key -T copy-mode-vi r send-keys -X cursor-right\; switch-client -T