Tmux is a great tool that allows you to have separate terminal sessions inside a single terminal window. Inside each session, you can have multiple windows, and each window can be separated into multiple panes. Take a look at this screenshot to get an idea. In this post, I would like to share and explain my configuration of this tool. Hopefully, you will find some nice tweaks in there that will help you to speed up your workflow.
Throughout the post, I assume that you have a basic understanding of Tmux. If not, I can recommend this short, but nice book.
Prefix
The default Prefix
is Ctrl+b
, which is rather awkward to use. Instead, I use Ctrl+Space
, which is easily accessible:
unbind C-b set -g prefix C-Space bind C-Space send-prefix
Settings
Start window numbering from 1 instead of 0. This makes window switching easier since 0
is placed after 9
on most keyboards, not before 1
:
set -g base-index 1
Start pane numbering from 1 instead of 0 to make it consistent with the window-numbering scheme above:
setw -g pane-base-index 1
Automatically re-number windows after one of them is closed. This keeps window number small so you can easily access them via Prefix + X
, where X
is the window’s number. Obviously, this works only when X
is 1-9
:
set -g renumber-windows on
Increase the scrollback history limit to make Tmux panes remember more lines:
set -g history-limit 10000
Disable mouse. This makes Tmux pass control directly to the used terminal emulator, so when I want, I can copy&paste as if I am not using Tmux. Since the options differ between Tmux 2.1 and older versions, I have to set these options conditionally depending on the used Tmux version:
# tmux < v2.1: if-shell "[[ `tmux -V | cut -d' ' -f2` -lt 2.1 ]]" "setw -g mode-mouse off" # tmux >= v2.1: if-shell "[[ `tmux -V | cut -d' ' -f2` -ge 2.1 ]]" "setw -g mouse off"
Pass xterm-style keys to make many key combinations work as expected:
setw -g xterm-keys on
Monitor window activity. Windows with activity are highlighted in the status line:
setw -g monitor-activity on
Prevent Tmux from displaying the annoying Activity in window X messages:
set -g visual-activity off
Enable vi-style keys instead of the default emacs-style keys (I am a Vim user):
set -g status-keys vi setw -g mode-keys vi
Disable the delay between an escape key press and subsequent characters. This increases Vim responsiveness:
set -sg escape-time 0
Enable UTF-8, which is my default encoding:
setw -g utf8 on set -g status-utf8 on
Enable 256 colors in the terminal emulator:
set -g default-terminal "screen-256color"
Key Bindings
Easy pane resizing with Prefix + Alt-h/j/k/l
:
bind -r M-h resize-pane -L 5 bind -r M-j resize-pane -D 5 bind -r M-k resize-pane -U 5 bind -r M-l resize-pane -R 5
Sane pane splitting with Prefix + |
and Prefix + -
. The default ones are %
and "
, which is highly non-intuitive:
# Pane splitting. bind | split-window -h -c "#{pane_current_path}" bind - split-window -v -c "#{pane_current_path}"
Movement of windows with Prefix + <
and Prefix + >
:
bind -r < swap-window -t -1 bind -r > swap-window -t +1
Make Prefix + 0
go to window number 10. Recall that I use window numbering starting from 1 instead of 0:
bind 0 select-window -t :10
Do not display the original window’s name when renaming it via Prefix + ,
. This makes renaming faster since one does not need to first erase the original name:
bind , command-prompt -p "(rename-window '#W')" "rename-window '%%'"
Do the same for session names (Prefix + $
):
bind '$' command-prompt -p "(rename-session '#S')" "rename-session '%%'"
Make Prefix + f
search only in window names (-N
), not in titles (-T
) or contents (-C
). The default is -CNT
. This is useful when you have a lot of windows and want to quickly switch between them:
bind f command-prompt -p "(find-window)" "find-window -N '%%'"
Reload Tmux configuration file with Prefix + R
:
bind R source-file ~/.tmux.conf \; display "Configuration reloaded."
Toggle pane synchronization with Prefix + S
:
bind S set synchronize-panes
Make Prefix + Ctrl-b
start copy mode and scroll one page up, just like Prefix + PgUp
does. This is useful as PgUp
is too far from the home row:
bind C-b copy-mode -u
Make Prefix + b
start copy mode, without scrolling up. This allows me to either just enter copy mode by pressing Prefix + b
or enter copy mode and scroll one page up with Prefix + Ctrl-b
:
bind b copy-mode
Make copy mode behave more like Vim. Moreover, make y
also copy the selected text to the system clipboard (including the primary
selection buffer in X11):
bind -t vi-copy v begin-selection bind -t vi-copy C-v rectangle-toggle bind -t vi-copy y copy-pipe "xclip -filter -selection clipboard | xclip -selection primary"
Seamless Navigation Between Vim and Tmux
I am a heavy Vim user. In Vim, I have configured Ctrl-h/j/k/l
to move between windows. In Tmux, the default bindings to move between panes are Prefix + h/j/k/l
. This forces one to pay unnecessary attention when running Vim inside Tmux. For example, should I use Ctrl-l
to move to the right “window” in Vim or should I use Prefix + l
because the right “window” is in, fact, a Tmux pane?
Fortunately, there is way out. The vim-tmux-navigator Vim plugin allows you to configure both Vim and Tmux to use the same keys for switching between windows and panes: Ctrl-h/j/k/l
(without Prefix
). This is great because now you do not have to distinguish between Vim windows and Tmux panes.
Full disclaimer: I actually do not use vim-tmux-navigator per se but rather a custom solution based on this blog post. The reason is that the plugin does not properly work when Vim is run over ssh or via other programs. See my full configuration files at the end of the present post for the implementation.
Appearance
My Tmux looks like this:
As you can see, I use a terminal with dark background and the current pane is shown with green lines. The currently selected window is shown in bold, and when a window has an activity flag set, its background in the status line is grey. The window list is shown on the left-hand side. The right-hand side shows the name of the current session and an indicator whether pane synchronization is enabled. The visible part of the topmost pane is Vim :).
To get the same appearance, use the following settings:
# Status line. set -g status-fg white set -g status-bg black set -g status-left "" set -g status-right "#{?pane_synchronized, #[bg=blue]SYNCHRONIZED#[default],} #S " # Window list. setw -g window-status-fg colour246 # grey setw -g window-status-bg black setw -g window-status-attr none setw -g window-status-format "#[fg=colour172]#I#[fg=white] #W " # Active window. setw -g window-status-current-fg white setw -g window-status-current-bg black setw -g window-status-current-attr bright setw -g window-status-current-format "#[fg=colour172]#I#[fg=white] #W#F" # Window activity. setw -g window-status-activity-fg colour246 # grey setw -g window-status-activity-bg black # Panes. set -g pane-border-fg white set -g pane-border-bg black set -g pane-active-border-fg green set -g pane-active-border-bg black # Command/message line. set -g message-fg white set -g message-bg black set -g message-attr bright # Make the window list appear at the left-hand side instead of at the center. set -g status-justify left
Plugins
I use the following two Tmux plugins:
- tmux-copycat — Enhances Tmux searches by allowing regex searches and providing various pre-defined searches. For example, you can quickly select, copy, and paste file paths, git-status files, SHA1 hashes, or URLs. This is faster than reaching for the mouse to do this. Check out this screencast to see the plugin in action.
- tmux-open — Allows you to open highlighted selection directly from Tmux copy mode, like opening links in a browser.
Shell Commands
I use a custom shell command tmux-select-each
from this stackoverflow.com post. When you run it, it clears activity flags on all windows in the current session. This is handy when you have activities in multiple windows and you want to clear them all in a single command. I bind this command to Space
, so after pressing Ctrl-Space Space
, all window activities are cleared:
bind Space run-shell "tmux-select-each '#S'"
Simply create a shell script with this code, make it executable, and put is somewhere on your PATH
.
Related Tools
Tmuxinator is a real time saver. It allows you to easily create and manage Tmux sessions. You specify the configuration of a session in a text file and run tmuxinator SESSION
to start it. Then, the tool creates all the windows and panes you have specified in the configuration file and, optionally, runs the prescribed commands. In this way, you can quickly open your Tmux sessions after a computer restart and resume your work. The tool also comes with shell completions for Bash, ZSH, and Fish. They allow you to use tab completion in your shell to complete session names after typing the tmuxinator
command.
My Configuration Files
My configuration files are available on Github. As you can see from them, I have described only some of the Tmux settings that I use. I encourage you to check out the configuration files in their entirety.
I love this post, thanks for sharing!