Quick background for anyone who doesn’t use tmux or screen: both are utilities that run in terminal that provide a bunch of nifty functionality. The big ones are:
-
The ability to disconnect from a remote host and reconnect via software like ssh or mosh, leaving the remote programs running. This also ensures that connection loss doesn’t kill off remote programs, making it – in my opinion, at any rate – pretty essential for
ssh
, thoughmosh
has more-limited built-in functionality. -
The ability to have multiple virtual terminals in one. There are a bunch of ways to do this (the Linux kernel has multiple ttys, X11 window managers or Wayland compositors can provide virtual desktops with different graphical virtual terminal programs running on each, and some virtual terminal programs provide a way to run multiple virtual terminals, usually in a tab or something). I prefer this route, though, because among other reasons, it works everywhere.
But they also provide a lot of other handy functionality, including things like file transfer via the terminal (well, screen
does), logging of what the current terminal is receiving, copy-pasting using vi or emacs keybindings, a terminal-level “status bar”, and such.
But I was doing work on my tmux
config, and thought that I’d go over my ~/.tmux.conf
, since it addressed a few things that annoyed me, and I figure that other people might have crashed into. Maybe others could share some of their neat tmux
or screen
stuff, if they’re in the moon:
unbind-key C-b
set-option -g prefix C-o
bind-key C-o send-prefix
This sets tmux
to use “Control-o” as the “prefix key”, which it uses before all other keybindings. Out-of-box, both screen
and tmux
grab keybindings which conflict with very-common emacs
keybindings, C-a
(beginning of line) and C-b
(previous character), respectively. Control-o is only used by (what I’d call) a fairly-obscure emacs feature, which you can still access by hitting Control-o twice. If you use vi keybindings (including in bash
and other programs that use readline, which default to using emacs-style keybindings), probably not necessary. Been using this for many years, ever since screen; it’s apparently a very common problem for new tmux
and screen
users.
set-option -g status-bg black
set-option -g status-fg cyan
By default, tmux
uses black text on a bright green background for the status bar; while this shows up well, for me, at least, this is kind of overwhelming. I prefer light text on a black background, or “dark mode”, as it’s popularly called these days. On some terminals, blue is hard to read out-of-box, and while I generally try to tweak my terminals to get it readable, cyan (bright blue) avoids this.
set-option -g status-left '#I|#H #(cut -d " " -f 1-4 /proc/loadavg)'
set-option -g status-right ""
set-option -g window-status-format ""
set-option -g window-status-current-format ""
The default tmux
configuration follows a convention where, for each “window” one opens, there’s a visual indicator showing a per-window entry. This is a common convention that many GUI programs use (opening a tab per window). Emacs traditionally has not done this, the idea being that you should be able to have many buffers open, that screen space is a limited resource and that if you want to switch the content that you’re looking at, you’re better-off bringing up a full-screen, scrollable list. tmux
can do this with prefix-key w out-of-box. If you have, say, ten open, there isn’t gonna be space to show 'em all. So I pull that out.
I do want to see the host, to ensure that I don’t confuse a tmux
instance running on Host A running ssh
in a window with sshing to Host B and running tmux
there.
Tmux defaults to showing a clock, which I get rid of with the above. I already have a clock on my desktop, and I don’t see much sense in throwing them elsewhere in each terminal. Tmux even defaults to showing a large one if you hit prefix-key t, though I can’t imagine that many people use that.
The current loadavg isn’t essential, but it’s a useful bit of status that tells one immediately whether some program is either still doing work or running away.
I don’t use window names: just numbers; so I hide names. It’s normally obvious from looking at a virtual termainal what something is, and switching by number is faster by keystroke.
set-option -g update-environment "DISPLAY WAYLAND_DISPLAY SWAYSOCK SSH_AUTH_SOCK"
This updates the environment variables in a tmux session when re-attaching. Various programs don’t do well if you detach from one session, log out of a graphical session, and then log in again; this fixes those. DISPLAY
is for X11, WAYLAND_DISPLAY
for Wayland, SWAYSOCK
for the Wayland Sway compositor (if you use that), and SSH_AUTH_SOCK
for ssh-agent
, which remembers a password to unlock an ssh key for a while.
bind-key H pipe-pane -o "exec cat >>$HOME/'tmux-#I.log'" \; display-message "Toggled logging to $HOME/tmux-#I.log"
This sets up tmux
to provide functionality that screen
has out-of-box – if you trigger it, it will start logging the output of the current console to a logfile in your home directory. Useful when you’ve already started a program and it’s spitting out information that you need a copy of, or if you want it to not disable color output (something that many programs do when they detect that their output is connected to a pipe rather than a tty); with my settings, Control-o H will toggle logging for a given window.
# emacs-style keys
bind-key C-n next-window
bind-key C-p previous-window
set -g mode-keys emacs
set -g status-keys emacs
I like emacs
-style keys rather than vi
-style.
bind-key C-c new-window -c "#{pane_current_path}"
While tmux has a default keybinding (prefix-key c) to create a new window at the current working directory that tmux was started at, it has no binding to start a new window at the current working directory being viewed in a window at the moment, something I frequently want to do – this makes prefix-key Control-c open a new shell at that point.
set -g visual-bell on
Beeping is obnoxious and in an open environment, can be disruptive to other people; many people switched to having their terminal flash rather than beep years back; many programs supported “visual bell”, which is just flashing rather than playing a sound. It’s not so bad these days, as Linux machines aren’t typically playing irritating beeps out of on-motherboard speakers, but in general, I don’t like having things beep.
Anyone else got useful snippets that they’d like to share that they use with tmux
or screen
?
I use CTRL-A locally on my computers and CTRL-B on servers. Keeps it easy and consistent to switch between windows and tasks.