~/il-codice-di-marco

Tmux: Minimal and Productive Configuration

Also available in: ๐Ÿ‡ฌ๐Ÿ‡ง English | ๐Ÿ‡ฎ๐Ÿ‡น Italiano

Three windows.

No panes.

Zero plugins.

One for the editor.

One for continuous compilation.

One for execution and tests.

This is my daily setup with tmux.

In this article Iโ€™ll show you how to build a minimal, portable, and productive configuration from scratch.

Introduction

What is Tmux?

tmux is a terminal multiplexer that lets you manage multiple sessions, windows, and panes in a single shell โ€” even remotely โ€” without losing anything when you disconnect.

Imagine being able to:

  • Split a single terminal window into multiple panes
  • Manage multiple projects simultaneously
  • Disconnect from a server without losing your work in progress
  • Speed up your workflow with custom keybindings

Why a Minimal Configuration?

In this guide we adopt a plugin-free approach for several reasons:

Speed: No plugin loading overhead Portability: Works on any system without dependencies Maintainability: Easy to understand Learning: You know exactly what every line does

Prerequisites and Installation

Installing Tmux

Ubuntu/Debian:

sudo apt update
sudo apt install tmux

macOS (with Homebrew):

brew install tmux

Verify Installation

tmux -V
# Expected output: tmux 3.5a or higher

Some Fundamental Concepts

Before getting started, itโ€™s essential to understand the hierarchy of tmux:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  SESSION: "web-project"                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  WINDOW 1: "editor"                       โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚  โ”‚
โ”‚  โ”‚  โ”‚   PANE 1    โ”‚     PANE 2           โ”‚   โ”‚  โ”‚
โ”‚  โ”‚  โ”‚   (vim)     โ”‚   (terminal)         โ”‚   โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  WINDOW 2: "server"                       โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚  โ”‚
โ”‚  โ”‚  โ”‚            PANE 1                    โ”‚ โ”‚  โ”‚
โ”‚  โ”‚  โ”‚          (server logs)               โ”‚ โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

A Session in tmux is a work context โ€” it could be an entire project, for example. You might have a session for the program youโ€™re working on, one for updating your blog, or another for configuring your NeoVim.

A window is, within a session, a virtual screen โ€” like a tab in your favorite browser.

A pane is a division within a window.

TermDescriptionAnalogy
SessionComplete work contextAn entire project
WindowVirtual screen within a sessionA browser tab
PaneDivision of a windowSplit screen

The Prefix Key

The prefix is the โ€œmagic keyโ€ that activates tmux commands. By default itโ€™s Ctrl+b, but in our configuration weโ€™ll change it to Ctrl+Space for ergonomics.

How it works:

  1. Press Ctrl+Space (the prefix)
  2. Release
  3. Press the command (e.g., c for new window)

โš ๏ธ Note: in some terminals or keyboard layouts Ctrl+Space might not work correctly. In that case Ctrl+a is an excellent alternative with universal support.

Initial Setup

First we need to create our configuration file:

touch ~/.tmux.conf

then, using our favorite editor (I donโ€™t think I need to tell you which one is mine ๐Ÿ˜€), letโ€™s add configurations step by step โ€” Iโ€™ll explain each one line by line.

General Settings

Changing the Prefix Key

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

What it does:

  • unbind C-b: Removes the default Ctrl+b binding
  • set -g prefix C-Space: Sets Ctrl+Space as the new prefix
  • bind C-Space send-prefix: Allows sending Ctrl+Space to the underlying application (by pressing it twice)

Why:

  • Ctrl+Space is more ergonomic: you press it with your thumb instead of your pinky

  • It doesnโ€™t interfere with common commands like Ctrl+b in Vim (page up)

  • Itโ€™s a less commonly used combination than Ctrl+b

    Some people prefer Ctrl+a โ€” I prefer space, but itโ€™s just a matter of finding the most practical combination for you that doesnโ€™t cause conflicts with the software you typically use in your terminal workflow.

Practical use:

# Create a new window:
Ctrl+Space, then c

# If an application needs Ctrl+Space:
Ctrl+Space, Ctrl+Space

Reload Configuration

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

What it does: Creates a keybinding to reload the configuration file without leaving tmux

Why: When you modify ~/.tmux.conf, instead of closing and reopening tmux, you can reload changes on the fly

Practical use:

# 1. Edit ~/.tmux.conf with your editor
vim ~/.tmux.conf

# 2. Save changes

# 3. In tmux, press:
Ctrl+Space, then r

# You'll see: "Configuration reloaded!"

Mouse Support

set -g mouse on

What it does: Fully enables mouse support in tmux

Enabled features:

  • Click on a pane to activate it
  • Drag borders between panes to resize
  • Click on a window in the status bar to select it
  • Scroll with the wheel to navigate history
  • Select text with the mouse and copy

Note: With the mouse active, to select text and copy it to the system clipboard, you may need to hold Shift while selecting

Practical use:

# Scenario: you have 4 panes open
# Instead of using Ctrl+hjkl to navigate,
# simply click on the desired pane

History Limit

set -g history-limit 20000

What it does: Sets the number of output lines stored per pane to 20,000

Why:

  • Default: only 2,000 lines
  • 20,000: lets you scroll back to much earlier output
  • Useful for analyzing long logs or finding past output

Practical use:

# After running commands with a lot of output:
Ctrl+Space, then [        # Enter copy mode
# Now you can scroll back through 20,000 lines
# Press q to exit

๐Ÿ“ Memory usage: 20,000 lines is roughly 2-3 MB per pane (depends on line length)


Numbering from 1

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

What it does: Makes window and pane numbering start from 1 instead of 0 as tmux defaults

Why:

Keyboard:  [1] [2] [3] [4] [5] [6] [7] [8] [9] [0]
With 0:     ^                               first window (awkward!)
With 1:     ^                               first window (convenient!)

Keys 1-9 are easier to reach than having to go all the way to 0 for the โ€œfirstโ€ window

Practical use:

Ctrl+Space, then 1    # Go to the FIRST window (not the second!)

Automatic Renumbering

set -g renumber-windows on

What it does: When you close a window, the subsequent ones are renumbered to maintain the sequence

Example:

Initial situation:  [1:vim] [2:server] [3:logs] [4:test]

Close window 2 (server)

โŒ WITHOUT renumber:  [1:vim] [3:logs] [4:test]     # Numbering with gaps!
โœ… WITH renumber:     [1:vim] [2:logs] [3:test]     # Always sequential!

Advantage: You donโ€™t have to โ€œskipโ€ numbers when switching between windows โ€” you always maintain a 1-2-3-4 sequence


True Color Support

set -ga terminal-overrides ",xterm-256color:Tc"

What it does: Enables true color support (16 million colors) instead of just 256 colors

Why:

  • Modern Vim/Neovim themes require true color
  • Gradients and color shadings
  • Richer syntax highlighting

Technical details:

  • -ga: append (adds instead of overwriting)
  • Tc: true color capability
  • xterm-256color: terminal type

Prerequisite: Your terminal must support true color (iTerm2, Alacritty, Kitty, modern terminals)


Window Splitting

Horizontal and Vertical Split

bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"

What it does:

  • | (pipe): splits the window horizontally (creates columns)
  • - (dash): splits the window vertically (creates rows)
  • -c "#{pane_current_path}": the new pane starts from the same directory

Visualization:

HORIZONTAL split (|):        VERTICAL split (-):
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚          โ”‚          โ”‚      โ”‚                     โ”‚
โ”‚  Pane 1  โ”‚  Pane 2  โ”‚      โ”‚      Pane 1         โ”‚
โ”‚  (vim)   โ”‚ (shell)  โ”‚      โ”‚      (vim)          โ”‚
โ”‚          โ”‚          โ”‚      โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚      Pane 2         โ”‚
                             โ”‚     (shell)         โ”‚
                             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Practical use:

# You're editing code and want a terminal on the right
Ctrl+Space, then |

# You're editing and want to see logs below
Ctrl+Space, then -

Mnemonic:

  • | looks like a vertical line โ†’ horizontal split
  • - looks like a horizontal line โ†’ vertical split

Without -c "#{pane_current_path}": The new pane would start from the home directory, forcing you to navigate to the current directory

๐Ÿ“ By default tmux allows splitting using % and " โ€” this configuration doesnโ€™t override them, theyโ€™ll still be usable


New Window in Current Directory

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

What it does: When you create a new window with c, it starts from the same directory as the current pane

Example:

# You're in: /home/user/projects/app/src
Ctrl+Space, then c
# The new window starts in: /home/user/projects/app/src
# (not in /home/user as it would by default)

Benefit: You donโ€™t have to cd every time you open a new window to work on the same project


Pane Navigation (Vim Style)

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

What it does: Navigates between panes using Ctrl+hjkl without pressing the prefix

Vim Layout:

        k (up)
        โ†‘
h (left) โ†+โ†’ l (right)
        โ†“
        j (down)

Practical use:

# You have 4 panes open
โ”Œโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”
โ”‚  1  โ”‚  2  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  3  โ”‚  4  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”˜

# You're in pane 1, want to go right (2):
Ctrl+l    # No prefix!

# From pane 2, want to go down (4):
Ctrl+j

โš ๏ธ Potential Conflict:

These bindings override some standard commands:

  • Ctrl+l: clear screen in bash/zsh
  • Ctrl+h: backspace in some terminals

If you donโ€™t want conflicts:

# Version with prefix (requires Ctrl+Space first)
bind h select-pane -L
bind l select-pane -R
bind k select-pane -U
bind j select-pane -D

Alternative for clear: If you lose Ctrl+l for clear, you can:

  • Use the clear or reset command
  • Create an alias: alias cls='clear'
  • Use Ctrl+Space then Ctrl+l (sends the command to the application)

Window Navigation

bind -n S-Left previous-window
bind -n S-Right next-window

What it does:

  • Shift+Left Arrow: go to the previous window
  • Shift+Right Arrow: go to the next window

Practical use:

# You have 3 windows: [1:vim] [2:server] [3:logs]
# You're in window 2 (server)

Shift+Left Arrow    # Go to [1:vim]
Shift+Right Arrow   # Back to [2:server]
Shift+Right Arrow   # Go to [3:logs]

Built-in alternatives:

Ctrl+Space, then n     # next window
Ctrl+Space, then p     # previous window
Ctrl+Space, then 1     # go to window 1
Ctrl+Space, then 2     # go to window 2
# ... etc

Pane Resizing

bind -n M-Left resize-pane -L 3
bind -n M-Right resize-pane -R 3
bind -n M-Up resize-pane -U 3
bind -n M-Down resize-pane -D 3

What it does: Resizes the current pane using Alt+Arrows, 3 cells at a time

Note: M = Meta (typically the Alt key or Option on Mac)

Practical use:

# Scenario: you have an editor on the left and a terminal on the right
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚            โ”‚      โ”‚
โ”‚   Editor   โ”‚ Term โ”‚
โ”‚            โ”‚      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”˜

# You want to give more space to the editor:
Alt+Right Arrow (multiple times)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”
โ”‚                  โ”‚T โ”‚
โ”‚     Editor       โ”‚e โ”‚
โ”‚                  โ”‚r โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”˜

Customization: If 3 cells is too much/too little, change the number:

bind -n M-Left resize-pane -L 5   # 5 cells at a time

Alternatives with prefix (and repeat):

# With -r (repeat) you can hold the key
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

Pane Synchronization

bind C-y set-window-option synchronize-panes\; display-message "Sync: #{?pane_synchronized,ON,OFF}"

What it does: Toggles input synchronization across all panes in the current window

When itโ€™s useful:

  • Running the same command on multiple SSH servers simultaneously
  • Updating multiple servers at the same time
  • Configuring multiple machines simultaneously

Practical use:

# Scenario: multi-server administration

# 1. Create 3 panes with SSH to different servers
Ctrl+Space |         # Split
ssh user@server1.com
Ctrl+Space |         # Split again
ssh user@server2.com
Ctrl+Space -         # Vertical split
ssh user@server3.com

# 2. Activate synchronization Ctrl+Space Ctrl+y

# 3. Type a command - it runs on ALL servers!

sudo apt update
sudo apt upgrade -y

# 4. Deactivate synchronization when done Ctrl+Space Ctrl+y

Copy Mode

Vi Mode

setw -g mode-keys vi

What it does: Enables Vi/Vim keybindings in copy mode (instead of the default Emacs bindings)

Copy Mode Navigation:

KeyAction
hleft
jdown
kup
lright
wnext word
bprevious word
0beginning of line
$end of line
gbeginning of document
Gend of document
/search
nnext occurrence
Nprevious occurrence

Selection and Copy

bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel

What it does:

  • v: starts visual selection (like in Vim)
  • y: โ€œyankโ€ (copy) the selection and exits copy mode

Complete workflow:

# STEP 1: Enter copy mode
Ctrl+Space, then [

# STEP 2: Navigate to the text you want to copy
# (use hjkl, or arrows, or search with /)

# STEP 3: Start selection
v

# STEP 4: Extend selection (move with hjkl)
# The selected text will be highlighted

# STEP 5: Copy
y

# STEP 6: Paste (in another pane)
Ctrl+Space, then ]

System Clipboard Integration

The base configuration copies to tmuxโ€™s internal buffer. To copy to the system clipboard:

Linux (with xclip):

# Install xclip
sudo apt install xclip

# Add to ~/.tmux.conf
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"

macOS:

# Use pbcopy (already present)
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"

With mouse selection:

# Linux
bind -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"

# macOS
bind -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"

Status Bar

Update Interval

set -g status-interval 5

What it does: Updates the status bar every 5 seconds

Why:

  • Keeps the clock updated
  • If you add custom scripts (e.g., battery, CPU), they get updated
  • 5 seconds is a good compromise between freshness and performance

Bar Position

set -g status-position bottom

Options:

  • bottom: at the bottom (default and most common)
  • top: at the top

When to use top: If you use a dropdown terminal (e.g., Guake, Yakuake) that appears from the top, a status bar at the top feels more natural


Left Bar Content

set -g status-left '<#S> #[default] '

What it shows:

  • #S: session name
  • Example: <web-project>

Useful variables:

VariableShows
#SSession name
#ICurrent window index
#PCurrent pane index
#WCurrent window name
#HFull hostname
#hHostname (name only)
#(command)Output of a command

๐Ÿ”ง Custom examples:

# With hostname
set -g status-left '#h <#S> | '

# With icons (requires a font with symbols)
set -g status-left '  #S | '

# With user info
set -g status-left '#(whoami)@#h <#S> | '

Right Bar Content

set -g status-right '%d/%m/%Y %H:%M '

What it shows: Date and time in European format: 08/02/2026 15:30

Date/time formats:

CodeOutputExample
%dDay08
%mMonth02
%YYear (4 digits)2026
%HHour (24h)15
%IHour (12h)03
%MMinutes30
%SSeconds45
%pAM/PMPM
%ADay of weekSunday
%BMonth nameFebruary

Custom examples:

# US format
set -g status-right '%m/%d/%Y %I:%M %p'
# Output: 02/08/2026 03:30 PM

# With day of week
set -g status-right '%A %d/%m/%Y %H:%M'
# Output: Sunday 08/02/2026 15:30

# With hostname
set -g status-right '#H | %d/%m/%Y %H:%M'
# Output: my-server | 08/02/2026 15:30

# With battery (requires custom script)
set -g status-right '๐Ÿ”‹ #(battery.sh) | %H:%M'
# Output: ๐Ÿ”‹ 87% | 15:30

Window Format

setw -g window-status-format ' #I:#W '
setw -g window-status-current-format ' [#I:#W] '

What it shows:

  • Normal windows: 1:vim 2:bash 3:server
  • Current window: [2:bash] (with square brackets)

Window variables:

VariableShows
#IWindow index (1, 2, 3โ€ฆ)
#WWindow name
#FWindow flag (* = current, - = last, Z = zoomed)
#TPane title

Customizations:

# With symbols
setw -g window-status-format ' #I:#W '
setw -g window-status-current-format ' โ–บ #I:#W โ—„ '

# With flags
setw -g window-status-format ' #I:#W#F '
setw -g window-status-current-format ' #I:#W#F '

# Minimal
setw -g window-status-format '#I'
setw -g window-status-current-format '[#I]'

Status Bar Colors

set -g status-style "bg=#1d2021,fg=#d5c4a1"

What it does: Sets the background (bg) and text color (fg) of the status bar

Supported color formats:

Hex:

set -g status-style "bg=#1d2021,fg=#d5c4a1"

Color names:

set -g status-style "bg=black,fg=white"
# Colors: black, red, green, yellow, blue, magenta, cyan, white

256 colors:

set -g status-style "bg=colour235,fg=colour250"
# colour0 ... colour255

RGB (true color):

set -g status-style "bg=#1d2021,fg=#d5c4a1"

Current Window Color

setw -g window-status-current-style "bg=#458588,fg=#1d2021,bold"

What it does: The active window will have a blue background (#458588), dark text (#1d2021) in bold

Text attributes:

# Combination of attributes
setw -g window-status-current-style "bg=blue,fg=white,bold,underscore"

# Available attributes:
# - bold
# - dim
# - underscore (underlined)
# - blink
# - reverse (swaps fg and bg)
# - italics

Performance

Escape Time

set -sg escape-time 10

What it does: Reduces to 10ms the time tmux waits after ESC to see if itโ€™s part of a sequence

Why it matters: tmux default: 500ms (half a second!)

When you press ESC in Vim:

โŒ WITH 500ms: Vim waits โ†’ noticeable delay โ†’ frustration
โœ… WITH 10ms:  Vim responds โ†’ instant โ†’ happiness

Impact: Crucial for those using Vim/Neovim inside tmux. Switching from insert to normal mode becomes instant

Donโ€™t set it to 0: 0 might cause some valid escape sequences to be lost. 10 is the recommended minimum


Window Title

set -g set-titles on
set -g set-titles-string '#T'

What it does: Allows applications to change the terminal window title


Essential Commands

Session Management

# Creating sessions
tmux new -s session-name           # New session with name
tmux new -s project -n editor      # With initial window name

# Listing sessions
tmux ls                            # From outside tmux
Ctrl+Space s                       # Inside tmux (interactive)

# Attaching to sessions
tmux attach -t session-name        # Reconnect
tmux a -t name                     # Short form
tmux attach                        # To the last session

# Renaming session
Ctrl+Space $                       # Rename current session

# Detaching
Ctrl+Space d                       # Detach
Ctrl+Space D                       # Choose which session to detach

# Killing sessions
tmux kill-session -t name          # From outside
Ctrl+Space :                       # Then type: kill-session
exit                               # From the last window of the session

Window Management

# Creating and navigating
Ctrl+Space c                 # New window
Ctrl+Space ,                 # Rename window
Ctrl+Space &                 # Close window (with confirmation)
Ctrl+Space w                 # List windows (interactive)

# Moving between windows
Ctrl+Space n                 # Next window
Ctrl+Space p                 # Previous window
Ctrl+Space [0-9]             # Go to window N
Ctrl+Space l                 # Last visited window
Ctrl+Space '                 # Prompt: window number
Ctrl+Space f                 # Search window by name

# With our config
Shift+Right                  # Next window
Shift+Left                   # Previous window

# Moving windows
Ctrl+Space :                 # Then: swap-window -t 2
                             # (swap with window 2)
Ctrl+Space .                 # Move and renumber

๐ŸŽฏ Tip: Give meaningful names to windows

Ctrl+Space ,    # Then type: "editor"
Ctrl+Space c    # New window
Ctrl+Space ,    # Type: "server"
Ctrl+Space c    # New window
Ctrl+Space ,    # Type: "logs"

# Result: [1:editor] [2:server] [3:logs]

Pane Management

# Creating panes
Ctrl+Space |                 # Horizontal split (our config)
Ctrl+Space -                 # Vertical split (our config)
Ctrl+Space %                 # Horizontal split (default)
Ctrl+Space "                 # Vertical split (default)

# Navigating between panes
Ctrl+hjkl                    # With our config (no prefix!)
Ctrl+Space o                 # Cycle through panes
Ctrl+Space ;                 # Go to last active pane
Ctrl+Space q                 # Show pane numbers

# Resizing
Alt+Arrows                   # With our config
Ctrl+Space Ctrl+Arrows       # Default (hold to repeat)

# Preset layouts
Ctrl+Space Space             # Cycle through layouts
Ctrl+Space Alt+1             # even-horizontal layout
Ctrl+Space Alt+2             # even-vertical layout
Ctrl+Space Alt+3             # main-horizontal layout
Ctrl+Space Alt+4             # main-vertical layout
Ctrl+Space Alt+5             # tiled layout

# Pane operations
Ctrl+Space x                 # Close pane (with confirmation)
Ctrl+Space z                 # Toggle zoom (temporary fullscreen)
Ctrl+Space !                 # Convert pane to window
Ctrl+Space {                 # Move pane left
Ctrl+Space }                 # Move pane right
Ctrl+Space Ctrl+o            # Rotate pane positions

Zoom tip: Ctrl+Space z is fantastic for temporarily focusing on a pane:

# You have 4 panes, one with Vim
โ”Œโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”
โ”‚ V  โ”‚  T โ”‚
โ”œโ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”ค
โ”‚ S  โ”‚  L โ”‚
โ””โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”˜

# Press Ctrl+Space z in the Vim pane
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚            โ”‚
โ”‚    VIM     โ”‚
โ”‚ (fullscr)  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

# Press Ctrl+Space z again to return to the 4 panes

Copy Mode

# Enter copy mode
Ctrl+Space [                 # Enter
q                            # Exit

# Navigation (with mode-keys vi)
hjkl                         # Up/down/left/right
w / b                        # Next/previous word
0 / $                        # Beginning/end of line
g / G                        # Beginning/end of document
Ctrl+u / Ctrl+d              # Half page up/down
Ctrl+b / Ctrl+f              # Full page up/down

# Search
/text                        # Search "text" forward
?text                        # Search "text" backward
n                            # Next occurrence
N                            # Previous occurrence

# Selection and copy (with our config)
v                            # Start selection
y                            # Copy and exit
Esc                          # Cancel selection

# Paste
Ctrl+Space ]                 # Paste from last buffer
Ctrl+Space =                 # Choose which buffer to paste from

Tips

Conditional Configuration

For different OSes:

# In ~/.tmux.conf

# OS-specific configurations
if-shell "uname | grep -q Darwin" \
    'bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"' \
    'bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"'

# tmux version-specific configurations
if-shell "test $(tmux -V | cut -d' ' -f2 | tr -d '[:alpha:]') -ge 3.2" \
    'set -g allow-passthrough on'

Problem: Tmux sessions are lost after reboot

Symptoms: After a server reboot, tmux sessions are gone

Explanation: Tmux saves sessions in RAM, not on disk

Solution: tmux-resurrect

Even though we prefer a plugin-free config, for this case itโ€™s worth it:

# 1. Install TPM (Tmux Plugin Manager)
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

# 2. Add to ~/.tmux.conf
# Plugin list
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-resurrect'

# Initialize TPM (keep this line at the end of the file)
run '~/.tmux/plugins/tpm/tpm'

# 3. Reload config
Ctrl+Space r

# 4. Install plugin
Ctrl+Space I (capital I)

# 5. Usage:
# - Save session: Ctrl+Space, Ctrl+s
# - Restore: Ctrl+Space, Ctrl+r

Useful Resources

Official Documentation

  • Tmux manual: man tmux in the terminal
  • Official guide: https://github.com/tmux/tmux/wiki
  • FAQ: https://github.com/tmux/tmux/wiki/FAQ

Cheatsheet

SESSIONS
--------
tmux                           New session
tmux new -s name               New session with name
tmux ls                        List sessions
tmux attach -t name            Attach to session
Ctrl+Space d                   Detach
Ctrl+Space s                   List sessions (interactive)
Ctrl+Space $                   Rename session

WINDOWS
-------
Ctrl+Space c                   New window
Ctrl+Space ,                   Rename window
Ctrl+Space w                   List windows
Ctrl+Space n                   Next window
Ctrl+Space p                   Previous window
Ctrl+Space [0-9]               Go to window N
Ctrl+Space &                   Close window

PANES
-----
Ctrl+Space |                   Horizontal split
Ctrl+Space -                   Vertical split
Ctrl+hjkl                      Navigate panes
Ctrl+Space z                   Toggle zoom
Ctrl+Space x                   Close pane
Ctrl+Space !                   Pane โ†’ window
Alt+Arrows                     Resize

COPY MODE
---------
Ctrl+Space [                   Enter copy mode
hjkl                           Navigate
v                              Start selection
y                              Copy
q                              Exit
/text                          Search
n / N                          Next/previous match

OTHER
-----
Ctrl+Space ?                   Show all keybindings
Ctrl+Space :                   Command prompt
Ctrl+Space r                   Reload config

Workflow Example: Rust Development ๐Ÿฆ€

My approach to Rust development with tmux is minimalist: one session per project, three dedicated windows, zero panes. Each window takes up the entire screen, keeping the focus on a single task at a time.

Setup: 3 Dedicated Windows

# Create a session dedicated to the project
tmux new -s rust-project
cd ~/projects/my-rust-app

Window 1: Editor

# tmux automatically creates the first window
Ctrl+Space ,               # Rename: "editor"
nvim src/main.rs

# The whole screen for code, no distractions
# Git workflow fully managed by fugitive:
# - :Git for status
# - :Git commit for commit
# - :Git push for push
# - etc.

Window 2: Cargo Watch

Ctrl+Space c               # New window
Ctrl+Space ,               # Rename: "watch"

# Automatic compilation on every save
cargo watch -x 'check --all-features' -x 'test --all-features'

Tip: Install cargo-watch if you donโ€™t have it:

cargo install cargo-watch

Window 3: Run & Test

Ctrl+Space c               # New window
Ctrl+Space ,               # Rename: "run"

# Here I manually run:
# - Specific tests
# - Cargo run
# - Other ad-hoc cargo commands
# - Complex git commands (only when fugitive isn't enough)

Final result:

[1:editor] [2:watch] [3:run]

Typical Workflow

# 1. Start or reattach the session
tmux attach -t rust-project

# 2. "editor" window (Ctrl+Space 1):
#    - Write code
#    - Save
#    - Git workflow via fugitive:
:Git                       # Git status
:Git add %                 # Stage current file
:Git commit                # Commit with message
:Git push                  # Push

# 3. "watch" window (Ctrl+Space 2):
#    - Immediately see compilation errors/warnings
#    - Tests run automatically

# 4. "run" window (Ctrl+Space 3):
#    - Specific tests:
cargo test test_authentication -- --nocapture

#    - Launch the application:
cargo run --release

#    - Complex git (only if necessary):
git rebase -i HEAD~3
git cherry-pick abc123

Fast Navigation

With our bindings, switching between windows is dead simple:

# Method 1: Direct number (the one I use most)
Ctrl+Space 1               # Editor
Ctrl+Space 2               # Watch
Ctrl+Space 3               # Run

# Method 2: Arrows (from our config)
Shift+Right                # Next window
Shift+Left                 # Previous window

# Method 3: Next/Previous
Ctrl+Space n               # Next
Ctrl+Space p               # Previous

This is my daily workflow for Rust with tmux: simple, effective, and fully integrated with Neovim. ๐Ÿฆ€


Complete Configuration File

# ==============================================
# MINIMAL AND PRODUCTIVE TMUX CONFIGURATION
# ==============================================

# --- GENERAL SETTINGS ---
unbind C-b
set -g prefix C-Space
bind C-Space send-prefix

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

set -g mouse on
set -g history-limit 20000
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
set -ga terminal-overrides ",xterm-256color:Tc"

# --- WINDOW SPLITTING ---
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"

# --- PANE NAVIGATION ---
bind -n C-h select-pane -L
bind -n C-l select-pane -R
bind -n C-k select-pane -U
bind -n C-j select-pane -D

# --- WINDOW NAVIGATION ---
bind -n S-Left previous-window
bind -n S-Right next-window

# --- PANE RESIZING ---
bind -n M-Left resize-pane -L 3
bind -n M-Right resize-pane -R 3
bind -n M-Up resize-pane -U 3
bind -n M-Down resize-pane -D 3

# --- PANE SYNC ---
bind C-y set-window-option synchronize-panes\; display-message "Sync: #{?pane_synchronized,ON,OFF}"

# --- COPY MODE ---
setw -g mode-keys vi
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel

# --- STATUS BAR ---
set -g status-interval 5
set -g status-position bottom
set -g status-left '<#S> #[default] '
set -g status-right '%d/%m/%Y %H:%M '
setw -g window-status-format ' #I:#W '
setw -g window-status-current-format ' [#I:#W] '

# --- THEME ---
set -g status-style "bg=#3c3836,fg=#eebd35"
setw -g window-status-current-style "bg=#458588,fg=#1d2021,bold"

# --- PERFORMANCE ---
set -sg escape-time 10
set -g set-titles on
set -g set-titles-string '#T'

Translation note: This article was originally written in Italian and translated into English with the assistance of an AI language model. While every effort has been made to preserve the original meaning and technical accuracy, minor nuances may differ from the source text.


Commenti