I’ve been using Tmux since 2013, and I wrote a blog post at that time. I somehow revisited my setup last year, but it was still on macOS (and using iTerm2). In the mean time I switched to Kitty, and I enjoyed using it for over a year and a half or so. It worked well in practice, I could use it on my Macbook and even on an OpenBSD machine. Same configuration, multiple OSs – what else? The only thing that I was really missing was getting notification for new activity in other tabs, session management and keyboard-based copy-pasting.
A few weeks ago, I decided to go back to the defaults (since default settings are often good, you know) and use Gnome terminal, which looks like a great terminal emulator, but without ligature support or multiplexing capabilities. Yet we can manage to get a comfy setup by adding Tmux on top of that. Hence I revised for the third time my Tmux config. I’ve been using Byobu on a remote server last year, but finally it didn’t bring me much more and I could do everything I wanted with Tmux alone. In fact, the only thing I really liked in Byobu was its ability to notify about available updates and reboot info so that my status
config file ended up with just those items:
tmux_left="session"
tmux_right="reboot_required updates_available load_average"
Since Byobu can use your screen or tmux config files, most of my settings remained in my .tmux.conf
file, and it acted as yet another backend.
I am now using Tmux every day, and it goes as smoothly as when I was using Kitty, except that I now have a few additional optins: I can switch my theme easily thanks to Gnome terminal, and I can manage multiple sessions at the same time. I can also detach the current session and close Gnome terminal, I know I will be able to restore everything afterwards unless I rebooted Ubuntu. Here are the core components of my Tmux setup:
Enable terminal features: In roder to get 256 color support, underline and undercurl etc., you’ll need to tweak the terminal-related settings. I personally use this:
set -g default-terminal "tmux-256color"
set -as terminal-overrides ',xterm*:Tc:sitm=\E[3m'
To enable colored underline and undercurl support, please refer to lsp-colors README.
You can change the default prefix key, whether you’re a past screen user or a current Emacs addict. I am fine with C-b
, but I added a second prefix key since I have an almost dead key next to my Esc keys (Esc
and CAPS Lock):
set-option -g prefix2 œ
You’ll likely need to copy-paste between different Tmux buffers. The combo C-[, <space>, <enter>, C-]
is kind of a mess, really. As a workaround, consider allowing Vim keybindings using the following settings:
bind Y copy-mode
setw -g mode-keys vi
bind-key -T copy-mode-vi v send -X begin-selection
bind-key -T copy-mode-vi 'C-v' send -X rectangle-toggle
set -g set-clipboard off
bind-key -T copy-mode-vi y send -X copy-pipe-and-cancel "xclip -i -selection clipboard"
Using these settings, you enter “copy-mode” by hitting <prefix> + Y
, then select text using Vim motion (e.g., v2w
to select the next two words, or C-v v5hj
to select a rectangular block of 5 chars x 2 lines), then copy and paste wherever you want using y
and S-C-v
. It’s all that simple, once you know it. I spent years tearing my hairs out before I discovered that it can that easy, really.
Other useful mappings, that you may need to adapt to your own taste: (Some are inspired by Byobu default keybindings.)
bind Q command-prompt -I "htop" -p "Quick window command: " "new-window '%%'"
bind R source-file ~/.tmux.conf \; display-message "Reloading config"
bind Y copy-mode
bind > swap-pane -D # swap current pane with the next one
bind < swap-pane -U # swap current pane with the previous one
bind Up resize-pane -U 5 # resize panes using arrow keys
bind Down resize-pane -D 5
bind Left resize-pane -L 5
bind Right resize-pane -R 5
bind m set -g mouse on \; display "Mouse Mode: on"
bind M set -g mouse off \; display "Mouse Mode: off"
bind-key -n F1 list-keys
bind-key -n F2 new-window
bind-key -n F3 previous-window
bind-key -n F4 next-window
bind-key -n F6 detach-client
bind-key -n F8 command-prompt "rename-window '%%'"
bind-key -n M-& selectp -t :.+
bind-key -n M-$ split-window -h -c "#{pane_current_path}"
bind-key -n M-! split-window -f -l 15 -c "#{pane_current_path}"
bind-key -n M-Left previous-window
bind-key -n M-Right next-window
bind-key -n M-a select-layout even-vertical
bind-key -n M-A select-layout even-horizontal
As for general settings, you may want to disable visual notification for activity in other windows but keep track of them more subtly using set -g visual-activity off
and setw -g monitor-activity on
, reduce <Esc>
timing for char codes using set -sg escape-time 0
, and automagically renumber window by setting set -g renumber-windows on
and, optionally, setw -g allow-rename off
if you don’t want your tab/window titles as fullwidth process names.
As for the status bar, it is usually a matter of opinion: I for one do not want to rely on external plugins (I can uptime
or date
myself in the terminal), and I want a minimalist design. Here we go:
And here is the code:
set -g status-interval 5
set -g status-justify left
set -g status-left ""
set -g status-position top
set -g status-right "#[fg=colour3] ♯#S "
if '! [ -z "$SSH_TTY" ]' 'set -g status-right "#[fg=colour145] #(whoami)@#h #[fg=colour3] ♯#S "'
set -g status-style fg=colour145
set -g window-status-current-format "#[fg=colour11,bg=colour3] #I "
set -g window-status-format "#[fg=colour145] #I "
set -g window-status-separator "#[fg=colour145]"
setw -g monitor-activity on
). If you don’t want to add all flags (#F
), you can still replace set -g window-status-current-format "#[fg=colour11,bg=colour3] #I "
with set -g window-status-current-format "#[fg=colour7,bg=colour4] #I#{?window_zoomed_flag,+,} "
, or even highlight other flags using convenient marks. I updated my config to display zoomed panes since I use this a lot and I sometimes forgot about them.Finally, beside personal keybindings, here are some useful builtin keybindings I keep using regularly:
<prefix> + z
to zoom in a specific pane (much more convenient than tweaking pane layout, IMHO);<prefix> + s
or <prefix> + w
to get a quick overview of my current sessions and windows;<prefix> + o
to cycle between panes in current windows (instead of <prefix> +
arrow keys);<prefix> + !
to convert current pane to a proper window (which is almost the equivalent of :tab split
in Vim);<prefix> + )
to cycle between existing sessions (technically, this is “move to next session”, but I don’t have that much sessions opened at the same time);<prefix> + $
to rename a session but this really is an edge case.I sometimes want to create a new session and attach the current window to it. Here is how we can do: Create a new session using <prefix> + :new
, then <prefix> + :move-window -s #name:#pane
, where #name
is the name of the current session in which the #pane
number is. A typical command is :move-window -s main:2
to move “pane number 2” (from session “main”) to the newly created session.
That’s it! I hope you will enjoy Tmux.
$HOME/.tmux.conf
, and enjoy all the customizations!!♪ Hiatus Kaiyote • Red Room