tmux mit vim und 80 Columns Breite im Split-Layout
Ich verwende gern tmux
mit
vim
und einigen Terminals nebeneinander. Dabei
gefällt mir das folgende Layout am besten:
+-----------------------------------+------------------+
| | Pane 1 |
| Pane 0 | bash |
| VIM | 80 chars |
| Alles minus 80 Chars | |
| +------------------+
| | Pane 2 |
| | bash |
| | 80 chars |
| | |
| +------------------+
| | Pane 3 |
| | bash |
| | 80 chars |
| | |
+-----------------------------------+------------------+
Das Vollbild-Terminal ist in mehrere tmux-Panes eingeteilt: Ein Haupt-Pane, in dem der Editor läuft (und da seine eigenen Splits macht) und mehrere kleinere Panes, in denen jeweils eine Shell läuft, in der dann SSH, Git oder sonst was passiert. Diese sollen bitte die standardmäßigen 80 Zeichen breit sein. Deren Anzahl steigt und fällt je nach Bedarf. Wenn ein Terminal mal in voller Größe gebraucht wird, um breite Diffs anzuzeigen oder bei anderen Dingen mit Platzbedarf, kann in das Terminal hinein gezoomt werden.
Weil das natürlich niemand von Hand immer auf die richtige Größe ziehen
will, vor allem wenn man am Laptop arbeitet und der verschieden große
Monitore (HD, 1440p) nochmal angesteckt haben kann, muss man das
Anpassen der Breite natürlich
automatisieren Zwischen den Splits in
vim
und den Panes in tmux
kann ich mit Hilfe von Ctrl-hjkl
navigieren.
Damit das alles auch farblich schön zusammen passt, passt sich die
Statuszeile von tmux
automatisch dem Farbschema
von vim
(mit dem
airline
-Plugin) an.
Automatisch die Breite anpassen
Leider hat tmux
keine eingebaute Funktion zur
Festsetzung der Breite einer Pane auf eine Anzahl von Columns (d.h.
Zeichen), nur Prozente. Ein Shellscript hilft bei der Berechnung der
Differenz zu den gewünschten 80 Zeichen:
$HOME/.local/bin/sizetmux.sh
, adaptiert von
StackOverflow:
#!/bin/bash
WANTED=80
CURRENT=$(tmux list-panes | awk -F"[ x:\\\[\\\]]+" '/^1:/{print $2}')
if [[ "${CURRENT}" -gt "${WANTED}" ]];
then
((DIFFERENCE = "${CURRENT}" - "${WANTED}"))
tmux resize-pane -R -t 1 "${DIFFERENCE}"
elif [[ "${CURRENT}" -lt "${WANTED}" ]];
then
((DIFFERENCE = "${WANTED}" -"${CURRENT}"))
tmux resize-pane -L -t 1 "${DIFFERENCE}"
fi
Das Script ist relativ einfach: Ist Pane 1 breiter als 80 Zeichen, wird sie um die Differenz verkleinert, sonst vergrößert, bei 80 Zeichen passiert nichts. Es reicht hier, Pane 1 zu verändern - die Breite von Pane 0 ergibt sich aus der Differenz zur Bildschirmbreite und alle weiteren Panes sind gleich breit wie Pane 1.
$HOME/.tmux.conf
(Auszug)
# Create new pane in current directory
bind -n M-n split-window -t :.0 -c "#{pane_current_path}" \;\
swap-pane -s :.0 -t :.1 \;\
select-layout main-vertical \;\
run "~/sizetmux.sh"
# Kill pane
bind -n M-c kill-pane -t :. \;\
select-layout main-vertical \;\
run "~/sizetmux.sh" \;\
select-pane -t :.+
# Rotate counterclockwise
bind -n M-j rotate-window -U \; select-pane -t 0
# Rotate clockwise
bind -n M-k rotate-window -D \; select-pane -t 0
# Focus selected pane
bind -n M-Enter swap-pane -s :. -t :.0 \; select-pane -t :.0
# Refresh layout
bind -n M-r select-layout main-vertical \;\
run "~/sizetmux.sh"
Daraus ergeben sich dann die Tastenkombinationen, mit denen das oben beschriebene Layout hergestellt wird:
Alt+n
: weitere Pane öffnen und Layout anpassenAlt+c
: Pane schließen und Layout wieder anpassenAlt+j
,Alt+k
: Die Panes im bzw. gegen den Uhrzeigersinn rotierenAlt+Enter
: Die aktuell ausgewählte Pane auf Position 0 schiebenAlt+r
: Das Layout wieder anpassen, falls es durcheinander geraten ist (etwa weil man die Shell mitCtrl+d
geschlossen hat
Außerdem gelten die normalen Shortcuts von tmux
weiter: die zum Wechseln der aktuell fokussierten Pane und auch
Ctrl+b z
, bei der eine Pane auf ganzer Höhe und
Breite des Terminals angezeigt wird.
vim
-Integration: Navigation
Damit es sich möglichst uniform anfühlt, habe ich mir die
Tastenkombinationen zum Wechseln zwischen Splits im
vim
-Fenster und tmux
-Panes
angeglichen und mit einem Script für vim integriert:
Weil tmux
per default nicht die gleichen
Buchstaben bei den Tastenkombinationen verwendet wie
vim
, habe ich das auch noch in der
.tmux.conf
angeglichen. Die Buchstaben von
vim
machen ohnehin mehr Sinn.
$HOME/.tmux.conf
(Auszug)
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n C-H if-shell "$is_vim" "send-keys C-h" "select-pane -L"
bind-key -n C-J if-shell "$is_vim" "send-keys C-j" "select-pane -D"
bind-key -n C-K if-shell "$is_vim" "send-keys C-k" "select-pane -U"
bind-key -n C-L if-shell "$is_vim" "send-keys C-l" "select-pane -R"
bind-key -n C-\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"
Ab dann gelten also die Navigation Ctrl
+ Richtung
sowohl in vim
als auch in
tmux
vim
und tmux
optisch angleichen: statusline
In meinem vim
verwende ich
airline um eine hübsche
Leiste zu haben, passend zu meinem restlichen Theme auch mit
solarized
-Design. Um das gleiche Design auch mit
tmux zu bekommen, sind drei Dinge notwendig:
- airline und
airline-themes
im
vim
installieren (Doku dazu jeweils bei GitHub) - tmuxline im
vim
installieren und einmalig mit:TmuxlineSnapshot $HOME/.tmuxcolors.conf
die Farben ins Heimverzeichnis schreiben lassen - In der
$HOME/.tmux.conf
noch oben einfügen:source-file $HOME/.tmuxcolors.conf
Startet man jetzt tmux
und darin
vim
neu, sollte man jeweils die gleiche (nicht die
selbe!) Statuszeile vorfinden.