12 KiB
Tmux
Introduction
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
kitty 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 labeled 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 TPM, 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.
Plugin | Why |
---|---|
tpm | TPM itself |
tmux-sensible | Better defaults I can’t be bothered to change myself |
tmux-yank | Better copy/pasting |
tmux-prefix-highlight | Tell me which prefix I’m using |
tmux-resurrect | Persist tmux sessions across system restarts |
nordtheme/tmux | Nord 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
"~ncmpcpp -q" btop ssh
set -g @resurrect-processes '<<resurrect-processes()>>'
Keybindings
First of all, 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”.
Keybinding | Command | Prefix to go to |
---|---|---|
« |
select-window -p | |
» |
select-window -n | |
Tab |
windows | |
w |
pane | |
y |
copy-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.
<<gen-keybinds()>>
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épo 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.
Keybinding | Command | Prefix to go to |
---|---|---|
/ |
split-window -h -c "#{pane-current_path}" | |
- |
split-window -v -c "#{pane-current_path}" | |
c |
select-pane -L | |
t |
select-pane -D | |
s |
select-pane -U | |
r |
select-pane -R | |
f |
resize-pane -Z | |
. |
pane-resize |
<<gen-keybinds(keybinds=pane-prefix, prefix="pane")>>
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.
Keybinding | Command | Prefix to go to |
---|---|---|
c | resize-pane -L 5 | pane-resize |
t | resize-pane -D 5 | pane-resize |
s | resize-pane -U 5 | pane-resize |
r | resize-pane -R 5 | pane-resize |
C | resize-pane -L | pane-resize |
T | resize-pane -D | pane-resize |
S | resize-pane -U | pane-resize |
R | resize-pane -R | pane-resize |
<<gen-keybinds(keybinds=pane-resize-prefix, prefix="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.
Keybinding | Command |
---|---|
c | new-window |
n | next-window |
p | previous-window |
<<gen-keybinds(keybinds=windows-prefix, prefix="windows")>>
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 to move 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
Keybinding | Command |
---|---|
v | send-keys -X begin-selection |
C-v | send-keys -X rectangle-toggle |
y | send-keys -X copy-selection-and-cancel |
C | send-keys -X top-line |
J | send-keys -X jump-to-backward |
S | send-keys -X scroll-up |
R | send-keys -X bottom-line |
T | send-keys -X scroll-down |
c | send-keys -X cursor-left |
t | send-keys -X cursor-down |
s | send-keys -X cursor-up |
r | send-keys -X cursor-right |
<<gen-keybinds(keybinds=copy-mode-vi-prefix, prefix="copy-mode-vi")>>