tmux: reload bash config across all panes and sessions

Yesterday I got myself into tmux and I love it!

tmux is a terminal multiplexer. It lets you switch easily between several programs in one terminal, detach them (they keep running in the background) and reattach them to a different terminal.

I’ve been using Zellij for several months prior to this. Which I must thank for getting me introduced to the world of terminal multiplexers. However I’ve been running into several issues with it, that got me looking for an alternative:

  • Session manager entires keep shifting and popping in and out randomly. This is the most frustrating thing, probably number one cause for me to look for a change.
  • Occasional crashes during session switching.
  • No ability to toggle between last two used sessions.
  • No number hotkey assignment for tabs.
  • Need to match Zellij theme with your terminal theme. They are two separate things.

The switch

A fantastic start into tmux are these two videos from typecraft over at YouTube. The basics are wonderfully explained there as well as some key configuration. This got me going immediately.

Here’s a documented .tmux.conf a arrived at after a day or two:

# Settings

# Change leader key to something more ergonomic
# Note: On MacOS disable the shortcut to change keyboard input language first in Settings.
set -g prefix C-Space
# Allow mouse interactions like focusing windows and panes and resizing
set -g mouse on
# Simplify the status bar look: white text on black background
set -g status-style bg=black,fg=white
# Disable hostname, date and time display in the status bar
set -g status-right ""
set -g status-position top
# Use vim style navigation
set -g mode-keys vi
# Number windows starting from 1, instead of 0
set -g base-index 1
# When window is closed, refresh the numbering
set -g renumber-windows on
# Change the look of session name in the status bar
set -g status-left "#[fg=blue]#S#[default] #[dim]โ†’#[default] "
# Do not truncate session names too early
set -g status-left-length 100

# Keybindings

# Shortcut for live reload of tmux config
unbind r
bind r source-file ~/.tmux.conf

# Last session toggle
bind S switch-client -l

# Maximize pane
bind z resize-pane -Z

# vim like pane navigation
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

# Set new windows and panes in the current directory
bind c new-window -c "#{pane_current_path}"
bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"

Superpowers: issuing commands to all panes in all sessions

I almost forgot what I wanted to write about initially. So here’s a ready made alias I use to reload bash config across all my tmux bash sessions. This is sooo useful when I for example add something like a new alias in my .bashrc. Previously I’d have to manually source the config in each pane where I’d want to use the alias, which is a pain. Now it’s just one command:

alias reload-bash-config-in-bash-panes=$'tmux list-panes -a -F \'#{session_name}:#{window_index}.#{pane_index} #{pane_current_command}\' | awk \'$2 == "bash" {print $1}\' | xargs -I{} tmux send-keys -t {} "source ~/.bashrc" C-m'

This ensures the source command is only executed in panes that are running “bash”. It won’t affect your neovim instances for example, or other programs where it could cause unintended consequences.

Layouts: GitOps for workspaces

In Zellij, layouts are build in and a wonderful feature. In tmux land, there is tmuxinator–a separate program–that handles layout definition via YAML files and starting sessions based on those layouts. It’s simple and I got going with it immediately.

Here’s a layout I use to run this blog in development environment:

name: klevo
root: ~/projects/klevo

windows:
  - edit:
      layout: main-vertical
      panes:
        - #bash
        - nvim
  - server:
      layout: even-horizontal
      panes:
        - docker compose up
        - ruby -rwebrick -e'WEBrick::HTTPServer.new(:Port => 8083, :DocumentRoot => ("#{Dir.pwd}/_site")).start'

tmux and neovim are the two things I wish I learned much earlier in my career. Mastering these tools provided an immense ergonomic boost to my workflows. It’s a joy to fly through projects and tasks in a fast, consistent, repeatable and simple environment, exactly suited to my needs.

My current tmux configuration running inside Ghostty terminal.