Last active
January 7, 2026 15:13
-
-
Save frobware/2c24a2519e24b956d571da29829b1c30 to your computer and use it in GitHub Desktop.
tmux.conf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # On macOS Sequoia 15.2, the Nix-generated default-command uses | |
| # reattach-to-user-namespace, which causes the shell to default to | |
| # bash even though $SHELL is set to /bin/zsh. Override these to ensure | |
| # the correct shell is used. I don't know why or when this behaviour | |
| # changed. | |
| set-option -g default-shell "$SHELL" | |
| set-option -g default-command "$SHELL" | |
| # Unbind all key bindings in the 'copy-mode-vi' table to use Emacs key bindings throughout. | |
| unbind-key -a -T copy-mode-vi | |
| # Unbind the default prefix key 'C-b'. | |
| unbind C-b | |
| # Set a new prefix to 'C-o', which is Emacs friendly. | |
| set -g prefix C-o | |
| # Allow sending literal C-o to applications by pressing C-o C-o. | |
| bind C-o send-prefix | |
| # Set the style of the clock mode to display time in 12-hour format. | |
| setw -g clock-mode-style 12 | |
| # Set the escape time to 0 milliseconds, reducing latency in | |
| # recognising keybindings. | |
| set -s escape-time 0 | |
| # Silence the bell notification. | |
| set -g bell-action none | |
| # Silence the visual feedback in the status bar. | |
| set -g visual-bell off | |
| # Make tmux more user-friendly by setting base index to 1 (default is 0) for windows and panes. | |
| set -g base-index 1 | |
| set -g pane-base-index 1 | |
| # Enable automatic renumbering of windows when a window is closed. | |
| set -g renumber-windows on | |
| # Set the maximum number of commands to remember in the command history. | |
| set -g history-limit 10000 | |
| # Enable mouse support. | |
| set -g mouse on | |
| # Use Emacs key bindings for copy mode and command mode. | |
| set -g mode-keys emacs | |
| set -g status-keys emacs | |
| # Place the status line at the top. | |
| set -g status-position top | |
| # Refresh the status bar faster by setting the interval to 1 second. | |
| set -g status-interval 1 | |
| # Monitor activity in other windows and alert when they change. | |
| set -wg monitor-activity on | |
| # Set the display time for tmux messages to 1s. | |
| set -g display-time 1000 | |
| # Enable automatic renaming of windows based on the current command or | |
| # application. This allows tmux to dynamically change the window name | |
| # based on what's running inside the window, which can be helpful in | |
| # quickly identifying the content of each window. | |
| set-option -g automatic-rename on | |
| # Allow applications inside tmux to request a window name change. This | |
| # complements the automatic-rename setting by permitting applications | |
| # (like certain scripts or tools) to set a custom window name if | |
| # they're designed to do so. | |
| set-option -g allow-rename on | |
| # Capture the last 10000 lines of pane history, save it to a file, and | |
| # then open it in the specified $EDITOR in a new window. | |
| bind e capture-pane -S -10000 \; save-buffer /tmp/tmux-buffer \; \ | |
| new-window "$EDITOR -e \"(aim/open-tmux-buffer)\"" | |
| # Bind keys for splitting windows. | |
| bind - split-window -v # Split window vertically | |
| bind | split-window -h # Split window horizontally | |
| bind "'" split-window -h # Split window horizontally | |
| # Bind keys for navigating through windows. | |
| bind -r p previous-window # Cycle to the previous window | |
| bind -r n next-window # Cycle to the next window | |
| bind -r C-p previous-window # Cycle to the previous window with Ctrl-p | |
| bind -r C-n next-window # Cycle to the next window with Ctrl-n | |
| # Bind a key for creating a new window at the current path. | |
| # bind-key -n C-t new-window -c "#{pane_current_path}" | |
| bind t new-window -c "#{pane_current_path}" | |
| # Bind keys for selecting a window by its index. | |
| bind -n M-1 select-window -t 1 | |
| bind -n M-2 select-window -t 2 | |
| bind -n M-3 select-window -t 3 | |
| bind -n M-4 select-window -t 4 | |
| bind -n M-5 select-window -t 5 | |
| bind -n M-6 select-window -t 6 | |
| bind -n M-7 select-window -t 7 | |
| bind -n M-8 select-window -t 8 | |
| bind -n M-9 select-window -t 9 | |
| # Bind keys for navigating through windows. | |
| bind C-w last-window # Go to the last active window | |
| # Bind keys for navigating through panes. | |
| bind o last-pane # Go to the last active pane (C-o o) | |
| bind h select-pane -L # Go to the pane to the left | |
| bind j select-pane -D # Go to the pane below | |
| bind k select-pane -U # Go to the pane above | |
| bind l select-pane -R # Go to the pane to the right | |
| bind z resize-pane -Z # Toggle pane zoom | |
| # Bind keys for tmux command prompt, pane displaying, entering copy mode, reloading config file, listing keys, and detaching. | |
| bind : command-prompt | |
| bind q display-panes | |
| bind c copy-mode | |
| bind r source-file ~/.config/tmux/tmux.conf \; display "Reloaded!" | |
| bind ? list-keys | |
| bind d detach | |
| # Update the environment variables when reattaching to tmux. | |
| set -ag update-environment "SSH_TTY SSH_CLIENT SSH_CONNECTION DISPLAY LOCALE_ARCHIVE LANG LANGUAGE LC_ALL" | |
| # Enable aggressive-resize to resize windows to the size of the | |
| # current pane if all windows are shown. | |
| setw -g aggressive-resize on | |
| # Allow for Alt|Cmd-<N> ala gnome-terminal if the terminal is Alacritty. | |
| if-shell -b '[[ "${TERM:-}" =~ alacritty ]]' { | |
| bind -n M-1 select-window -t 1 | |
| bind -n M-2 select-window -t 2 | |
| bind -n M-3 select-window -t 3 | |
| bind -n M-4 select-window -t 4 | |
| bind -n M-5 select-window -t 5 | |
| bind -n M-6 select-window -t 6 | |
| bind -n M-7 select-window -t 7 | |
| bind -n M-8 select-window -t 8 | |
| bind -n M-9 select-window -t 9 | |
| } | |
| # Enable pane synchronisation. | |
| bind-key = set-window-option synchronize-panes | |
| # Bind keys for page navigation in copy mode. | |
| bind -T copy-mode 'C-v' send-keys -X page-down | |
| bind -T copy-mode 'M-v' send-keys -X page-up | |
| # This bind command allows you to insert a new window at a specific | |
| # position within the tmux window list. It opens a command prompt | |
| # asking for the window index and then runs the shell command based on | |
| # whether the window at that index already exists. | |
| # | |
| # - 'command-prompt -p "Insert window at:"' opens a prompt asking the | |
| # user for the window index where the new window should be inserted. | |
| # | |
| # - If the window exists at the given index (%1): | |
| # 1. 'tmux select-window -t %1' tries to select the window at that | |
| # index. | |
| # 2. 'tmux new-window -a' creates a new window immediately to the | |
| # right of the currently active window. | |
| # 3. 'tmux swap-window -s %1 -t $((%1+1))' swaps the new window | |
| # into the next position, pushing the window at %1 one position | |
| # to the right. | |
| # | |
| # - If the window does not exist: | |
| # 1. 'tmux new-window' creates a new window. | |
| # 2. 'tmux move-window -t %1' moves this new window to the target | |
| # index. | |
| # | |
| # - Finally, it restores the user's previous window selection: | |
| # 1. 'tmux select-window -t #{window_id}' returns to the original | |
| # window. | |
| # 2. 'tmux select-window -t %1' re-selects the target window. | |
| # | |
| # Example 1: Inserting at position 1 | |
| # Suppose there are windows at positions 1, 2, and 3: | |
| # - You insert at position 1. | |
| # - A new window is created to the right of the current window, and | |
| # the window at position 1 is pushed to position 2. | |
| # | |
| # Example 2: Inserting at position 5 | |
| # Suppose there are windows at positions 1, 2, 3, and 4: | |
| # - You insert at position 5. | |
| # - The new window is created at position 5, leaving the other | |
| # windows unchanged. | |
| # | |
| # This allows users to neatly insert a window into an existing window | |
| # list while keeping the focus on their original window before the | |
| # operation. | |
| bind i command-prompt -p 'Insert window at:' ' \ | |
| run-shell " \ | |
| if tmux select-window -t %1; then \ | |
| tmux new-window -a; \ | |
| tmux swap-window -s %1 -t \$((%1+1)); \ | |
| else \ | |
| tmux new-window; \ | |
| tmux move-window -t %1; \ | |
| fi; \ | |
| tmux select-window -t #{window_id}; \ | |
| tmux select-window -t %1; \ | |
| "' | |
| # Set Emacs key bindings in copy mode. | |
| setw -g mode-keys emacs | |
| # Allow tmux to set the title of the terminal emulator. | |
| set -g set-titles on | |
| set -g set-titles-string "#T" | |
| # This line sets the default terminal for tmux. | |
| # | |
| # See: https://github.com/tmux/tmux/wiki/FAQ: | |
| # | |
| # Inside tmux TERM must be "screen", "tmux" or similar (such as | |
| # tmux-256color"). Don't bother reporting problems where it isn't! | |
| set -g default-terminal "tmux-256color" | |
| # This line sets a terminal override for various TERM types, appending | |
| # the "Tc" capability. "Tc" tells tmux to support true color (24-bit | |
| # color), assuming that the terminal it's running in also supports | |
| # true color. Ditto for "RGB". "Tc" is a Tmux extension. | |
| set -ag terminal-overrides ",alacritty*:Tc" | |
| set -ag terminal-overrides ",alacritty*:RGB" | |
| # OSC 52 clipboard handling for tmux over mosh. | |
| # | |
| # mosh ignores OSC 52 sequences with an empty selector (52;;...), so the | |
| # target must be explicit ("c" for the system clipboard). tmux passes | |
| # the selector and payload separately via terminfo 'Ms': | |
| # | |
| # %p1 = selector (often "c") | |
| # %p2 = base64 payload | |
| # | |
| # The "%p1%.0s" construct consumes parameter 1 while printing zero | |
| # characters. In terminfo formatting, ".0" is a precision specifier | |
| # meaning “emit nothing”. This ensures the selector is accepted by | |
| # tmux but never emitted, preventing it from leaking into the payload. | |
| # | |
| # The payload is emitted unchanged from %p2, keeping app-generated | |
| # OSC 52 (e.g. from terminal Emacs) intact while always presenting | |
| # mosh with a non-empty target. | |
| set -as terminal-overrides ',*:Ms=\E]52;c%p1%.0s;%p2%s\007' | |
| # Add XT (Extended Terminal) feature to all terminals. This feature is | |
| # used by Tmux to identify whether a terminal supports certain | |
| # sequences, such as the OSC 52 escape sequence for clipboard | |
| # integration. | |
| set -a terminal-features '*:XT' | |
| # Set Tmux to rely on OSC 52 clipboard integration. | |
| set -g set-clipboard on | |
| # Allow passthrough of escape sequences unrecognised by Tmux. This | |
| # means if Tmux receives an escape sequence that it doesn't | |
| # understand, it will forward it to the terminal as-is. This can be | |
| # useful in certain scenarios, for example, when certain applications | |
| # or utilities use their own custom escape sequences. | |
| # https://github.com/spudlyo/clipetty/issues/25#issuecomment-1327472790 | |
| set -g allow-passthrough on | |
| # Set word boundaries for mouse text selection to match Alacritty's | |
| # semantic_escape_chars. | |
| set-option -g word-separators ",│`|:\"' ()[]{}<>\t" | |
| # ---------------------------------------------- | |
| # Enhanced Pane Awareness Configuration for tmux | |
| # ---------------------------------------------- | |
| # | |
| # The following configurations provide a more nuanced view of the | |
| # processes running inside the tmux panes: | |
| # | |
| # 1. Primary Conditional for `zsh` Command: | |
| # - The format checks if the command being executed in the pane is | |
| # `zsh`. If it is, it applies specific formatting. | |
| # | |
| # 2. Path Formatting for `zsh`: | |
| # - Two transformations are applied: | |
| # a. Substitutes the home directory with `~`. | |
| # b. Extracts the basename of the current path. | |
| # | |
| # Result: If you're in `/home/user/documents`, it displays | |
| # `documents`. | |
| # If in `/home/user`, it displays `~`. | |
| # | |
| # 3. Formatting for Other Commands: | |
| # - Displays the current command. | |
| # - Checks if the current path is not the home directory. | |
| # - If it's not, it appends the basename of the | |
| # - pane_current_path in brackets. | |
| # - If in the home directory, just displays the command name | |
| # - without brackets. | |
| # | |
| # For instance, with a command like `emacs`: | |
| # - In `/projects/ai`: The display is `emacs(ai)`. | |
| # - In `/home/user`: The display is just `emacs`. | |
| setw -g window-status-format "#F<#I:#{?#{==:#{pane_current_command},zsh},#{s|$HOME|~|;s|.*/||:pane_current_path},#{pane_current_command}#{?#{!=:#{pane_current_path},$HOME},(#{s|.*/||:pane_current_path}),}}>" | |
| setw -g window-status-current-format "#F<#I:#{?#{==:#{pane_current_command},zsh},#{s|$HOME|~|;s|.*/||:pane_current_path},#{pane_current_command}#{?#{!=:#{pane_current_path},$HOME},(#{s|.*/||:pane_current_path}),}}>" | |
| # Set the status line background to dark green and foreground to | |
| # bright yellow. | |
| set-option -g status-style bg=darkgreen,fg=brightyellow | |
| # Set the message area background to bright yellow and foreground to | |
| # black. | |
| set-option -g message-style bg=brightyellow,fg=black | |
| # Mode styles (like copy mode) are set to 'yellow' background and | |
| # 'black' foreground for clarity and distinction from normal panes. | |
| setw -g mode-style 'bg=yellow,fg=black' | |
| set-option -g window-status-activity-style bg=grey25 | |
| set-option -g window-status-current-style bg=darkgreen,fg=brightwhite,bold,reverse | |
| set-option -g window-status-last-style fg=orange,bold | |
| set-option -g window-status-style bg=darkgreen,fg=brightwhite | |
| # Set the inactive pane border's foreground to a muted green and | |
| # background to default. | |
| set-option -g pane-border-style 'fg=darkgreen,bg=default' | |
| # Set the active pane border's foreground to yellow and background to | |
| # default. | |
| set-option -g pane-active-border-style 'fg=yellow,bg=default' | |
| # Source the tmux-extras.conf file if it exists. | |
| if-shell -b '[[ -f "$HOME/.tmux-extras.conf" ]]' { | |
| source ~/.tmux-extras.conf | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment