Unlocking Terminal Productivity with tmux

tmux is your secret weapon. Imagine banishing cluttered browser tabs, fearlessly updating your terminal, and rearranging your workspace with superhuman agility. With tmux, you'll gain unparalleled control over your terminal sessions.

Unlocking Terminal Productivity with tmux

If you spend a lot of time working in the terminal, tmux (terminal multiplexer) is about to become your new best friend. Tmux empowers you to split your terminal into multiple panes, manage numerous windows, and detach sessions so your work stays safe even if your connection drops. Picture yourself as the airbender of the terminal, gracefully manipulating your workspace.

Why tmux Matters

  • Banish Browser Tabs: Ditch those cluttered browser tabs that hold different terminal sessions. With tmux, organize everything within a single terminal window.
  • Terminal Emulator Upgrades? No Worries: Update your terminal emulator without losing your running processes – tmux has your back.
  • Flexibility: Effortlessly shift panes and windows around to achieve your ideal terminal layout.

Getting Started

Let's break down a simplified installation and configuration process.

Installation (macOS)

brew install tmux

Ubuntu/Debian

sudo apt-get update
sudo apt-get install tmux

Fedora/CentOS/RHEL

sudo dnf install tmux

Arch Linux

sudo pacman -S tmux

Helpful Function

Let's add a handy tat function to your .bashrc or .zshrc file. This function streamlines creating and attaching to tmux sessions:

function tat {
  name=$(basename `pwd` | sed -e 's/\.//g')

  if tmux ls 2>&1 | grep "$name"; then
    tmux attach -t "$name"
  elif [ -f .envrc ]; then
    direnv exec / tmux new-session -s "$name"
  else
    tmux new-session -s "$name"
  fi
}

Whenever you start a project, just cd into the directory and type tat – magic!

Core Configuration (~/.tmux.conf)

Let's dive into some tmux customization essentials:

There are two config paths you can use

  • ~/.tmux.conf
  • ~/.config/tmux/tmux.conf
# Enable mouse support!
set -g mouse on

# Larger command history 
set -g history-limit 102400 

# User-friendly window numbering 
set -g base-index 1 
setw -g pane-base-index 1 

# Avoid odd window renumbering after a window closes
set -g renumber-windows on 

# Key Bindings (Customization Central!)
unbind C-b  # Get rid of the default prefix
set -g prefix C-a  # Ctrl-a is our new friend
bind C-a send-prefix

Enable mouse support

set -g mouse on - This allows you to interact with tmux using your mouse. You'll be able to click to switch between panes, resize them, and even select text for copying. This is the 21st century, after all.

Larger command history

set -g history-limit 102400 - Increases the number of past commands tmux remembers for each pane. This is super helpful when you need to recall a previously used command—you can search further back in your history.

User-friendly window numbering

set -g base-index 1
setw -g pane-base-index 1

These lines make tmux start numbering windows and panes from 1 instead of 0. This aligns with common intuition, making it easier to map your tmux layout mentally.

Avoid odd window renumbering after a window closes.

set -g renumber-windows on - Prevents unexpected window number changes after you close a window. Your remaining windows will retain their original numbers, maintaining consistency.

Key Bindings

unbind C-b
set -g prefix C-a
bind C-a send-prefix

This is where you start personalizing tmux shortcuts.

I prefer the C-a key binding because it makes it easier to press with a single hand.

  • The first line removes the default tmux prefix (Ctrl-b).
  • The second line replaces it with Ctrl-a, giving you a new starting point for all your tmux commands.
  • The third line makes the tmux intercept the key command and prevents sending the keybinding to any sub-processors

Windows

Here's where things get exciting. Let's streamline tmux navigation:

# Copy Mode Enhancements
unbind-key -T copy-mode-vi v 
bind-key -T copy-mode-vi v send-keys -X begin-selection
# Add more copy mode bindings for selection, copying, etc.

# Quick Configuration Reload
bind r source-file ~/.tmux.conf \; display "Config reloaded!"

# Pane and Window Management
bind c new-window -c '#{pane_current_path}'  # New window in the same directory
bind '\' split-window -h -c '#{pane_current_path}'  # Horizontal split
bind - split-window -v -c '#{pane_current_path}'  # Vertical split

To enter navigation mode in tmux, press Ctrl-a [. Once in this mode, you can navigate the buffer as if you were inside a VIM buffer. Here are some useful actions you can take:

  • Search for things with /; find the next match with n and the previous match with N.
  • Start a visual selection with v; switch to rectangle mode with Ctrl-v.
  • Copy the visual selection into your OS clipboard with y. This will automatically cancel the selection. You can also copy text by simply highlighting it with your mouse.

More Window management

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

Press Ctrl-a c to open a new window with the same path.

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

Use Ctrl-a \ to open a vertical split (it’s the same key with the | symbol). Use Ctrl-a - to open a horizontal split.

bind b break-pane -d

Press Ctrl-a b to break the current pane into a new window.

Another shortcut I use all the time is Ctrl-a z to expand the current pane full-screen. Press it again to return to your previous pane configuration.

tmux + Vim: A Powerful Duo

If you live in Vim, this integration snippet is for you:

First of all, install vim-tmux-navigator and add these lines to your ~/.vimrc:

nnoremap <C-J> <C-W>j
nnoremap <C-K> <C-W>k
nnoremap <C-H> <C-W>h
nnoremap <C-L> <C-W>l

These will allow us to switch between Vim splits by just pressing Ctrl-j instead of Ctrl-w j. Then add this to your ~/.tmux.conf:

is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h'  'select-pane -L'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j'  'select-pane -D'
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k'  'select-pane -U'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l'  'select-pane -R'
tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'
if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\'  'select-pane -l'"
if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\'  'select-pane -l'"

bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
bind-key -T copy-mode-vi 'C-\' select-pane -l

A Polished Status Bar

Let's customize the tmux status bar to display useful info in a visually pleasing way (the code snippet provided has great ideas!).

## Pane Settings & Style
## ----------------------

# set pane colors - highlight active pane
setw -g pane-border-style fg=colour235
setw -g pane-active-border-style bg=default,fg=colour245

# Dim-out any pane that's not active.
setw -g window-style fg=white,bg=colour236
setw -g window-active-style fg=white,bg=colour235

# Command / Message line
# set-window-option -g message-style fg=black,bold,bg=colour11

# split panes using | (horizontally) and - (vertically)
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %

# switch panes using Alt-arrow without prefix
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

# turn the status bar on
set-option -g status on

# set update frequencey (default 15 seconds)
set -g status-interval 10

# center window list for clarity
set -g status-justify centre   # [left | centre | right]
#set-option -g status-position top  # position the status bar [top, bottom]

## set color for the whole status bar
set -g status-style bg=colour240,fg=default

## Status Bar
## ----------

#Centre Bar
set-window-option -g window-status-style fg=colour118,bg=colour04
set-window-option -g window-status-current-style fg=red,bright,bg=default,bright
set-window-option -g window-status-last-style fg=grey,bold,bg=default,bright
set-window-option -g window-status-separator |

# Left Side Bar
set-option -g status-left-length 75   # default 10
set-option -g status-left "[#[fg=green,bright] S: #S, #[fg=colour208]W #I-#W, #[fg=colour178]P: #P #[fg=white]]"

# Right Side Bar
set-option -g status-right-length 120   # default 50
#set-option -g status-right "#[fg=grey,dim,bg=default] uptime: #(uptime | cut -f 4-5 -d\" \" | cut -f 1 -d\",\")"
#set -ag status-right "#[fg=cyan,bg=default]  %a %d #[default]"
set -g status-right "#[fg=colour245]%d %b #[fg=colour256] %R"

# Activity Alerts
set-option -g status-interval 10           # Update the status line every 60 seconds (15 is default)
set-window-option -g monitor-activity on   # highlights the window name in the status line
set -g visual-activity on

Levelling Up: Beyond the Basics

We've just scratched the surface! Explore more tmux magic:

  • Plugins: Enhance functionality further with plugins.
  • Themes: Style your tmux environment.
  • Advanced Scripting: Automate workflows within tmux sessions.

Check out the configuration and resources below if you want to dive deeper into tmux configurations.

GitHub - tmux-plugins/tmux-sensible: basic tmux settings everyone can agree on
basic tmux settings everyone can agree on. Contribute to tmux-plugins/tmux-sensible development by creating an account on GitHub.

tmux-sensible

Let me know if you'd like me to elaborate on specific areas or provide tailored examples. Tmux is truly a powerful tool to revolutionize your terminal experience.