My Tmux Configuration

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:

My Tmux status.

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.

1 Comments

Leave a Comment.