Skip to content

Instantly share code, notes, and snippets.

@vancanhuit
Last active June 29, 2026 11:56
Show Gist options
  • Select an option

  • Save vancanhuit/d32b1615406f8af27a01535fd75a53f2 to your computer and use it in GitHub Desktop.

Select an option

Save vancanhuit/d32b1615406f8af27a01535fd75a53f2 to your computer and use it in GitHub Desktop.
TMUX configuration
##### ~/.tmux.conf
##### Debian WSL2, tmux 3.6b
##### No plugins, no clip.exe, no external clipboard integration
##### Prefix
set -g prefix C-a
unbind C-b
bind C-a send-prefix
##### Server / terminal behavior
set -s default-terminal 'tmux-256color'
set -as terminal-features ",xterm-256color:RGB"
# Truecolor + undercurl/colored underlines for Neovim diagnostics.
set -as terminal-overrides ',*:Tc'
set -as terminal-overrides ',*:Smulx=\E[4::%p1%dm'
set -as terminal-overrides ',*:Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m'
# Pass cursor shape and other DECSCUSR sequences through for Neovim guicursor.
set -as terminal-features ',*:cstyle'
# Good defaults for modern terminals and editors.
set -g focus-events on
set -g escape-time 10
# Extended keys so Neovim sees C-S-h, C-/, etc. through tmux.
set -s extended-keys on
set -as terminal-features ',*:extkeys'
# Allow image protocols and other escape sequences to pass through.
set -g allow-passthrough on
# Let tmux set the terminal clipboard and accept OSC52 writes from apps
# (e.g. Neovim yanks) since there is no xclip/wl-copy provider installed.
set -s set-clipboard on
##### Indexing / windows / panes
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
# Keep lots of scrollback.
set -g history-limit 100000
# Update outside terminal title.
set -g set-titles on
# Keep tmux server useful when sessions are closed.
set -g detach-on-destroy off
##### Reload config
bind r source-file ~/.tmux.conf \; display-message "Reloaded ~/.tmux.conf"
##### Mouse
set -g mouse on
# The wiki notes that mouse drag normally copies and exits copy mode.
# This changes mouse drag release so it does not automatically copy/exit.
# Use keyboard copy bindings instead.
unbind -T copy-mode MouseDragEnd1Pane
unbind -T copy-mode-vi MouseDragEnd1Pane
##### Vi-style copy mode and command prompt
set -g mode-keys vi
set -g status-keys vi
bind [ copy-mode
# Vi-like copy mode bindings.
bind -T copy-mode-vi v send -X begin-selection
bind -T copy-mode-vi C-v send -X rectangle-toggle
bind -T copy-mode-vi y send -X copy-selection-and-cancel
bind -T copy-mode-vi Enter send -X copy-selection-and-cancel
bind -T copy-mode-vi Escape send -X clear-selection
bind -T copy-mode-vi q send -X cancel
# Useful line navigation.
bind -T copy-mode-vi H send -X start-of-line
bind -T copy-mode-vi L send -X end-of-line
# Search in copy mode.
bind -T copy-mode-vi / command-prompt -p "search down:" "send -X search-forward '%%'"
bind -T copy-mode-vi ? command-prompt -p "search up:" "send -X search-backward '%%'"
bind -T copy-mode-vi n send -X search-again
bind -T copy-mode-vi N send -X search-reverse
# Prefix + ] remains the default paste-from-buffer binding.
# Prefix + y just shows a preview of the latest tmux buffer.
bind y display-message "Latest tmux buffer: #{buffer_sample}"
##### Pane and window creation
# Open new windows/panes in the current pane's working directory.
bind c new-window -c "#{pane_current_path}"
bind '"' split-window -v -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
# Easier split bindings.
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
##### Pane navigation and resizing
# Seamless navigation between Neovim splits and tmux panes (no prefix).
# When focused on a Neovim pane, C-h/j/k/l moves inside Neovim; otherwise tmux.
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'"
bind -n C-h if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
bind -n C-j if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
bind -n C-k if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
bind -n C-l if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
bind -T copy-mode-vi C-h select-pane -L
bind -T copy-mode-vi C-j select-pane -D
bind -T copy-mode-vi C-k select-pane -U
bind -T copy-mode-vi C-l select-pane -R
# Prefix-based pane selection remains available.
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind -r H resize-pane -L 5
bind -r J resize-pane -D 3
bind -r K resize-pane -U 3
bind -r L resize-pane -R 5
bind z resize-pane -Z
bind Space next-layout
##### Window navigation and ordering
bind -r C-h previous-window
bind -r C-l next-window
bind -r < swap-window -t -1 \; select-window -t -1
bind -r > swap-window -t +1 \; select-window -t +1
##### Safer destructive commands
bind x confirm-before -p "Kill pane #P? (y/n)" kill-pane
bind X confirm-before -p "Kill window #W? (y/n)" kill-window
##### Find / choose helpers
# Session picker.
bind s choose-tree -sZ
# Window picker.
bind w choose-tree -wZ
# Find panes/windows by visible text, title, or window name.
# This mirrors the wiki's description of the default find-window behavior.
bind f command-prompt -p "find:" "find-window '%%'"
# Command prompt.
bind : command-prompt
##### Status bar
set -g status on
set -g status-position bottom
set -g status-interval 5
set -g status-justify left
# Palette (truecolor). Tweak here to retheme everything.
set -g @c_amber '#e0af68'
set -g @c_amber2 '#d79921'
set -g @c_blue '#7aa2f7'
set -g @c_red '#f7768e'
set -g @c_green '#9ece6a'
set -g @c_fg '#c0caf5'
set -g @c_dim '#565f89'
set -g @c_bg '#1a1b26'
set -g @c_panel '#24283b'
set -g @c_ink '#1a1b26'
set -g status-style "bg=default,fg=#565f89"
set -g status-left-length 80
set -g status-right-length 120
# Prefix / copy-mode indicator + session name.
set -g status-left "#{?client_prefix,#[fg=#{@c_ink} bg=#{@c_amber} bold] PREFIX ,#{?pane_in_mode,#[fg=#{@c_ink} bg=#{@c_blue} bold] COPY ,#[fg=#{@c_ink} bg=#{@c_amber} bold] #S }}#[default] "
# Right: zoom/sync flags, working dir, date/time. No shell-outs.
set -g status-right "#{?pane_synchronized,#[fg=#{@c_ink} bg=#{@c_red} bold] SYNC #[default] ,}#{?window_zoomed_flag,#[fg=#{@c_ink} bg=#{@c_amber} bold] Z #[default] ,}#[fg=#{@c_blue}]#{b:pane_current_path} #[fg=#{@c_dim}]%Y-%m-%d #[fg=#{@c_amber}]%H:%M #[default]"
setw -g window-status-format " #[fg=#{@c_dim}]#I:#W#{?window_last_flag,-,}#{?window_activity_flag,!,} "
setw -g window-status-current-format " #[fg=#{@c_amber} bold]#I:#W#{?window_zoomed_flag,*,} "
setw -g window-status-separator ''
# Subtle highlight for windows with activity/bell.
setw -g window-status-activity-style "fg=#f7768e,blink"
set -g monitor-activity on
set -g visual-activity off
set -g message-style "bg=#24283b,fg=#c0caf5"
set -g message-command-style "bg=#24283b,fg=#e0af68"
set -g mode-style "bg=#e0af68,fg=#1a1b26"
set -g display-panes-active-colour "#e0af68"
set -g display-panes-colour "#565f89"
set -g clock-mode-colour "#e0af68"
##### Pane border styling
set -g pane-border-style "fg=#24283b"
set -g pane-active-border-style "fg=#e0af68"
# Optional pane title in border.
# Uncomment these if you like visible pane titles.
# set -g pane-border-status top
# set -g pane-border-format '#[bold]#{pane_title}#[default]'
##### Quality of life
# Clear pane screen and tmux scrollback.
bind C-l send-keys C-l \; clear-history
# Rename window/session.
bind , command-prompt -I "#W" "rename-window '%%'"
bind '$' command-prompt -I "#S" "rename-session '%%'"
# Create and switch to a new session from inside tmux.
bind N command-prompt -p "new session name:" "new-session -d -s '%%' \; switch-client -t '%%'"
# Toggle synchronize-panes with a visible warning.
bind S setw synchronize-panes \; display-message "synchronize-panes: #{?pane_synchronized,on,off}"
##### ~/.tmux.conf
##### Debian, bash default shell, tmux 3.5a
##### No plugins, no external clipboard integration (OSC52 only)
##### Prefix
set -g prefix C-a
unbind C-b
bind C-a send-prefix
##### Server / terminal behavior
set -s default-terminal 'tmux-256color'
set -as terminal-features ",xterm-256color:RGB"
# Good defaults for modern terminals and editors.
set -g focus-events on
set -g escape-time 50
# Allow tmux itself to set the external terminal clipboard,
# while ignoring clipboard writes from applications inside tmux.
set -s set-clipboard external
##### Indexing / windows / panes
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
# Keep lots of scrollback.
set -g history-limit 100000
# Resize to the smallest client actively viewing a window, not the smallest attached.
setw -g aggressive-resize on
# Update outside terminal title.
set -g set-titles on
# Keep tmux server useful when sessions are closed.
set -g detach-on-destroy off
##### Reload config
bind r source-file ~/.tmux.conf \; display-message "Reloaded ~/.tmux.conf"
##### Mouse
set -g mouse on
# The wiki notes that mouse drag normally copies and exits copy mode.
# This changes mouse drag release so it does not automatically copy/exit.
# Use keyboard copy bindings instead.
unbind -T copy-mode MouseDragEnd1Pane
unbind -T copy-mode-vi MouseDragEnd1Pane
##### Vi-style copy mode and command prompt
set -g mode-keys vi
set -g status-keys vi
bind [ copy-mode
# Vi-like copy mode bindings.
bind -T copy-mode-vi v send -X begin-selection
bind -T copy-mode-vi C-v send -X rectangle-toggle
bind -T copy-mode-vi y send -X copy-selection-and-cancel
bind -T copy-mode-vi Enter send -X copy-selection-and-cancel
bind -T copy-mode-vi Escape send -X clear-selection
bind -T copy-mode-vi q send -X cancel
# Useful line navigation.
bind -T copy-mode-vi H send -X start-of-line
bind -T copy-mode-vi L send -X end-of-line
# Search in copy mode.
bind -T copy-mode-vi / command-prompt -p "search down:" "send -X search-forward '%%'"
bind -T copy-mode-vi ? command-prompt -p "search up:" "send -X search-backward '%%'"
bind -T copy-mode-vi n send -X search-again
bind -T copy-mode-vi N send -X search-reverse
# Prefix + ] remains the default paste-from-buffer binding.
# Prefix + y just shows a preview of the latest tmux buffer.
bind y display-message "Latest tmux buffer: #{buffer_sample}"
##### Pane and window creation
# Open new windows/panes in the current pane's working directory.
bind c new-window -c "#{pane_current_path}"
bind '"' split-window -v -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
# Easier split bindings.
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
##### Pane navigation and resizing
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind -r H resize-pane -L 5
bind -r J resize-pane -D 3
bind -r K resize-pane -U 3
bind -r L resize-pane -R 5
bind z resize-pane -Z
bind Space next-layout
##### Window navigation and ordering
bind -r C-h previous-window
bind -r C-l next-window
bind -r < swap-window -t -1 \; select-window -t -1
bind -r > swap-window -t +1 \; select-window -t +1
##### Safer destructive commands
bind x confirm-before -p "Kill pane #P? (y/n)" kill-pane
bind X confirm-before -p "Kill window #W? (y/n)" kill-window
##### Find / choose helpers
# Session picker.
bind s choose-tree -sZ
# Window picker.
bind w choose-tree -wZ
# Find panes/windows by visible text, title, or window name.
# This mirrors the wiki's description of the default find-window behavior.
bind f command-prompt -p "find:" "find-window '%%'"
# Command prompt.
bind : command-prompt
##### Status bar
set -g status on
set -g status-position bottom
set -g status-interval 5
set -g status-justify left
set -g status-style 'bg=default,fg=colour245'
set -g status-left-length 80
set -g status-right-length 120
# Prefix indicator + session name.
set -g status-left '#{?client_prefix,#[fg=colour16 bg=colour214 bold] PREFIX #[default] ,}#[fg=colour16 bg=colour214 bold] #S #[fg=colour214 bg=default]#[default] '
# Right: zoom/sync flags, host, then date/time. No external shell-outs.
set -g status-right '#{?window_zoomed_flag,#[fg=colour214 bold]Z ,}#{?pane_synchronized,#[fg=colour203 bold]SYNC ,}#[fg=colour245]#h #[fg=colour238]| #[fg=colour245]%Y-%m-%d #[fg=colour214 bold]%H:%M #[default]'
# Highlight windows with activity; show flags (zoom, etc.).
setw -g window-status-format ' #[fg=colour245]#I:#W#{?window_flags,#F,} '
setw -g window-status-current-format ' #[fg=colour16 bg=colour214 bold] #I:#W#{?window_zoomed_flag,*,} #[default]'
setw -g window-status-activity-style 'fg=colour203'
setw -g window-status-separator ''
# Highlight inactive windows that produce output, without bell noise.
setw -g monitor-activity on
set -g visual-activity off
set -g message-style 'bg=colour236,fg=colour231'
set -g mode-style 'bg=colour214,fg=colour16'
##### Pane border styling
set -g pane-border-style 'fg=colour238'
set -g pane-active-border-style 'fg=colour214'
# Optional pane title in border.
# Uncomment these if you like visible pane titles.
# set -g pane-border-status top
# set -g pane-border-format '#[bold]#{pane_title}#[default]'
##### Quality of life
# Clear pane screen and tmux scrollback.
bind C-l send-keys C-l \; clear-history
# Rename window/session.
bind , command-prompt -I "#W" "rename-window '%%'"
bind '$' command-prompt -I "#S" "rename-session '%%'"
# Create and switch to a new session from inside tmux.
bind N command-prompt -p "new session name:" "new-session -d -s '%%' \; switch-client -t '%%'"
# Toggle synchronize-panes with a visible warning.
bind S setw synchronize-panes \; display-message "synchronize-panes: #{?pane_synchronized,on,off}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment