Video

Want to see the full-length video right now for free?

Sign In with GitHub for Free Access

Notes

Navigation

Panes

Splitting / Creating Panes

I recommend adding the following mappings for creating panes / splitting windows:

bind-key - split-window -v  -c '#{pane_current_path}'
bind-key \ split-window -h  -c '#{pane_current_path}'

These mappings have the following three benefits over the default split-window mappings:

  • No shift required - Although minimal, having to hold the shift key is a bit more friction than I'd like for something I do as much as creating panes.
  • Memory / Visual Cue - The above mappings visually link to the way the screen will be split, making it extremely easy to remember which key splits for the desired orientation. (Note, the \ key is used, but the | character sharing the key cap is the visual mapping for that binding.)
  • Intuitive Directory Behavior - With the addition of the -c '#{pane_current_path}, new panes will be created in the directory of the pane you ran the key-binding from. This is much more intuitive than the default of using the directory the session was created in.

Pane Navigation

In a previous video we configure C-h, C-j, C-k, and C-l to navigate between panes without requiring the prefix key using the following configuration:

bind-key -n C-h select-pane -L
bind-key -n C-j select-pane -D
bind-key -n C-k select-pane -U
bind-key -n C-l select-pane -R

See the next video on Vim integration for an enhancement to these navigation commands that also allows for navigation with Vim using these same keys.

Resizing

The following configurations allow for resizing the active pane using shift or control and the arrow keys. These do not require the prefix key and as such can be repeated as needed.

# Fine adjustment (1 or 2 cursor cells per bump)
bind -n S-Left resize-pane -L 2
bind -n S-Right resize-pane -R 2
bind -n S-Down resize-pane -D 1
bind -n S-Up resize-pane -U 1

# Coarse adjustment (5 or 10 cursor cells per bump)
bind -n C-Left resize-pane -L 10
bind -n C-Right resize-pane -R 10
bind -n C-Down resize-pane -D 5
bind -n C-Up resize-pane -U 5

Zooming

If you temporarily want to focus on the contents of a single pane, you can use the zooming functionality added to tmux in version 1.9, which will cause the current pane to temporarily occupy the entire window. When ready, you can unzoom the pane and it will return to the position and size it originally occupied.

Pane zooming is bound by default to <prefix>z, and this acts as a toggle to both zoom a pane and unzoom as needed.

Windows

Creating Windows

Similar to panes, windows will default to opening in the directory of the session, rather than the directory of the current pane. This can be solved by mapping over the existing new-window map and adding the configuration:

bind c new-window -c "#{pane_current_path}"

Window Numbering Configuration

I recommend setting the following options to make the window numbering more logical and intuitive:

  • set -g base-index 1 - Start window numbering at 1
  • set -g renumber-windows on - Renumber windows as they are created and destroyed to keep the window numbers consistent with the count

Window Navigation

Navigation between windows is bound by default to <prefix>{n} where {n} is the window number. To go to window 3, use the key-binding <prefix>3, window 1 with <prefix>1, etc.

In addition, you can jump back and forth between two windows, a "current" and a "previous," using <prefix>l

Breaking a Pane Out to a New Window

Occasionally it can be useful to "break" a pane out of the current window and into a new window. This allows the process running in the pane to continue, but you are able to reclaim that pane's space in the current window.

bind-key b break-pane -d

Sessions

Creating Sessions

New sessions can be created by navigating to a directory while not connected to tmux, then running tmux new-session -s {name} where {name} is the desired name of the session. Almost as a rule I will name the session after the directory since I tend to open a session for each project / git repo I am working with. In order to simplify this, my collegues and I have built a simple script called tat which automates all of this. You can find the official version of this script in the thoughtbot dotfiles, and the source as shown in the video is included here as well:

#!/bin/sh
#
# Attach or create tmux session named the same as current directory.

session_name="$(basename "$PWD" | tr . -)"

session_exists() {
  tmux list-sessions | sed -E 's/:.*$//' | grep -q "^$session_name$"
}

not_in_tmux() {
  [ -z "$TMUX" ]
}

if not_in_tmux; then
  tmux new-session -As "$session_name"
else
  if ! session_exists; then
    (TMUX='' tmux new-session -Ad -s "$session_name")
  fi
  tmux switch-client -t "$session_name"
fi

Mark this as executable and place anywhere on your path and then you can use tat to create new sessions.

Additional Commands

  • Detach Session - tmux detach-session which is bound to <prefix>d will disconnect your tmux client while keeping the session alive.
  • List Sessions - tmux list-sessions which is aliased to tmux ls will list out the session names and a brief summary.

Session Navigation

Tmux provides the switch-client command for navigating between sessions, but it is slightly less intuitive than I'd like.

Instead, I typically use the choose-tree command, which displays list / tree of the available sessions and can be navigated using vim-like j/k navigation. We can bind this to C-j using:

bind-key C-j choose-tree

In addition to choose-tree, tmux provides a key binding for rapidly navigating between a current and previous session. This is bound to <prefix>L.

Scrollback / Copy Mode

We've written a post on the Giant Robots blog, Tmux Copy and Paste on OS X, which covers configuring tmux to provide a more intuitive copy and paste interaction and integration with the system. The relevant configuration lines are:

# Use vim keybindings in copy mode
setw -g mode-keys vi

# Setup 'v' to begin selection as in Vim
bind-key -t vi-copy v begin-selection
bind-key -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

# Update default binding of `Enter` to also use copy-pipe
unbind -t vi-copy Enter
bind-key -t vi-copy Enter copy-pipe "reattach-to-user-namespace pbcopy"

Note - OS X users will need to install reattach-to-user-namespace in order to allow tmux to interact with the system clipboard.

With the above configuration set for your tmux session, you can interact with copy mode using the following steps:

  1. <prefix> [ to start "copy-mode"
  2. Move to the text you want to copy using Vim-like key-bindings, i.e., k to move up a line, / to search, etc.
  3. v to start selection
  4. Move to end of text with Vim key-bindings, e.g. e for end of word. The selection will be highlighted
  5. y to copy the highlighted/selected text

The selected text will now be in your system clipboard.

Final Configuration

The .tmux.conf as of the end of step 3:

unbind C-b
set -g prefix C-s
bind-key -r C-s send-prefix

bind-key r source-file ~/.tmux.conf \; display-message "~/.tmux.conf reloaded"

bind-key -n C-h select-pane -L
bind-key -n C-j select-pane -D
bind-key -n C-k select-pane -U
bind-key -n C-l select-pane -R

set-option -g default-terminal "screen-256color"
set-option -g status-keys "emacs"

set-option -g status-left-length 50

set-option -g status-right " #(battery -t) "

bind-key - split-window -v  -c '#{pane_current_path}'
bind-key \ split-window -h  -c '#{pane_current_path}'

bind -n S-Left resize-pane -L 2
bind -n S-Right resize-pane -R 2
bind -n S-Down resize-pane -D 1
bind -n S-Up resize-pane -U 1

bind -n C-Left resize-pane -L 10
bind -n C-Right resize-pane -R 10
bind -n C-Down resize-pane -D 5
bind -n C-Up resize-pane -U 5

bind c new-window -c '#{pane_current_path}'

set-option -g base-index 1
set-option -g renumber-windows on

bind-key b break-pane -d

bind-key C-j choose-tree

# Use vim keybindings in copy mode
setw -g mode-keys vi

# Setup 'v' to begin selection as in Vim
bind-key -t vi-copy v begin-selection
bind-key -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

# Update default binding of `Enter` to also use copy-pipe
unbind -t vi-copy Enter
bind-key -t vi-copy Enter copy-pipe "reattach-to-user-namespace pbcopy"