chore(config): update terminal, tmux, and starship configurations

This commit is contained in:
Prad Nukala committed 2026-10-08 11:29:07 -04:00
1 parent f2802b3cd8
commit ce9886c2e7
10 files changed
+236 -50

No files matched your search

+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
# ~/.config/tmux/tab-label.sh — the non-editor tab label, kitty tab_bar.py's
# rule: the repo the pane's cwd belongs to (dir name if no repo, ~ at home).
# Editors (the open file) are handled in tmux.conf's automatic-rename-format.
# Args: $1 pane_current_path $2 window_id
path=$1 window=$2
if [[ $path == "$HOME" ]]; then
label='~'
else
dir=$path
while [[ -n $dir && ! -e $dir/.git ]]; do dir=${dir%/*}; done
root=${dir:-$path}
label=${root##*/}
fi
printf '%s' "$label"
# tmux runs #() jobs async and only re-checks a window's name on pane output,
# so after a `cd` the tab would keep the old label until the next keystroke.
# Re-arming automatic-rename makes tmux re-check now and pick up this output.
if [[ -n $window && $(tmux display -p -t "$window" '#W' 2>/dev/null) != *"${label:0:26}"* ]]; then
tmux set -w -t "$window" automatic-rename on >/dev/null 2>&1 &
fi
@@ -1,14 +1,14 @@
config:
fallback-icon: "\U000F08D9" # show when no definition is found
fallback-icon: "󰣙" # show when no definition is found
multi-pane-icon: "" # show when window has multiple panes (blank by default)
show-name: true # show the window name with the icon (defaults to false)
show-name: false # the label comes from automatic-rename-format in tmux.conf (cwd, as in kitty)
icon-position: "left" # show the icon to the "left" or "right" of the window name (defaults to left)
icons:
mprocs: "\U000F012A"
mprocs: "󰄪"
mm: ""
macmon: ""
make: ""
zsh: "\U000F07B7"
zsh: "󰞷"
nvim: ""
devbox: ""
psql: ""
@@ -16,11 +16,11 @@ icons:
lazygit: ""
gh: ""
tv: ""
docker: "\U000F0868"
docker: "󰡨"
bun: ""
node: ""
npm: ""
pnpm: ""
go: ""
bunx: "\U000F012A"
bunx: "󰄪"
claude: "󱜙"
+98 -13
View File
@@ -3,6 +3,10 @@ set -g prefix C-Space
set -g prefix2 C-b
bind -N "Send prefix" C-Space send-prefix
set-option -g renumber-windows on
set -g base-index 1
setw -g pane-base-index 1
# Config and help
bind -N "Reload configuration" q source-file ~/.config/tmux/tmux.conf \; display "Configuration reloaded"
bind -N "Show Tmux keybindings" ? display-popup -E -w 80% -h 70% -T "Tmux keybindings" "omarchy-menu-tmux-keybindings --print | less -R"
@@ -11,6 +15,7 @@ bind -N "Show Tmux keybindings" ? display-popup -E -w 80% -h 70% -T "Tmux keybin
setw -g mode-keys vi
bind -N "Begin selection" -T copy-mode-vi v send -X begin-selection
bind -N "Copy selection" -T copy-mode-vi y send -X copy-selection-and-cancel
bind -N "Search scrollback" / copy-mode \; command-prompt -p "search up:" "send -X search-backward '%%'"
# Pane Controls
bind -N "Split pane vertically" -n M-Enter split-window -v -c "#{pane_current_path}"
@@ -26,6 +31,23 @@ bind -N "Focus pane right" -n C-M-Right select-pane -R
bind -N "Focus pane up" -n C-M-Up select-pane -U
bind -N "Focus pane down" -n C-M-Down select-pane -D
# ctrl+h/j/k/l: vim-aware pane navigation, the tmux half of nvim's
# config.pane_nav. In an nvim/vim/fzf pane the key is forwarded so nvim moves
# between its own splits and, at its outer edge, hands off with
# `tmux select-pane -t $TMUX_PANE`; elsewhere tmux moves directly. "Is vim" is
# smart-splits' @pane-is-vim pane option or the pane's foreground command, read
# as a format (no ps fork per keypress). Ghostty passes these keys through
# (keybind = clear); prefix + ctrl+l is the clear-screen escape hatch.
bind -N "Focus pane left (vim-aware)" -n C-h if -F '#{||:#{@pane-is-vim},#{m/r:^(n?vim|vim|fzf)$,#{pane_current_command}}}' 'send-keys C-h' 'select-pane -L'
bind -N "Focus pane down (vim-aware)" -n C-j if -F '#{||:#{@pane-is-vim},#{m/r:^(n?vim|vim|fzf)$,#{pane_current_command}}}' 'send-keys C-j' 'select-pane -D'
bind -N "Focus pane up (vim-aware)" -n C-k if -F '#{||:#{@pane-is-vim},#{m/r:^(n?vim|vim|fzf)$,#{pane_current_command}}}' 'send-keys C-k' 'select-pane -U'
bind -N "Focus pane right (vim-aware)" -n C-l if -F '#{||:#{@pane-is-vim},#{m/r:^(n?vim|vim|fzf)$,#{pane_current_command}}}' 'send-keys C-l' 'select-pane -R'
bind -N "Focus pane left" -T copy-mode-vi C-h select-pane -L
bind -N "Focus pane down" -T copy-mode-vi C-j select-pane -D
bind -N "Focus pane up" -T copy-mode-vi C-k select-pane -U
bind -N "Focus pane right" -T copy-mode-vi C-l select-pane -R
bind -N "Clear screen" C-l send-keys C-l
bind -N "Resize pane left" -n C-M-S-Left resize-pane -L 5
bind -N "Resize pane down" -n C-M-S-Down resize-pane -D 5
bind -N "Resize pane up" -n C-M-S-Up resize-pane -U 5
@@ -71,10 +93,18 @@ set -g renumber-windows on
set -g history-limit 50000
set -g escape-time 0
set -g focus-events on
# Yazi inside tmux: OSC 52 clipboard, image passthrough, and the outer
# TERM/TERM_PROGRAM so yazi detects Ghostty/kitty graphics. Never bind M-[:
# tmux would eat the ESC [ of yazi's terminal-query replies.
set -g set-clipboard on
set -g allow-passthrough on
set -ga update-environment TERM
set -ga update-environment TERM_PROGRAM
setw -g aggressive-resize on
set -g detach-on-destroy off
# Killing a session switches only to a *detached* one, else detaches: with
# one session per Ghostty window, `off` would land on (and mirror) a session
# another window is showing.
set -g detach-on-destroy no-detached
set -g extended-keys on
set -g extended-keys-format csi-u
set -ag terminal-features "xterm-kitty:extkeys"
@@ -88,28 +118,83 @@ set -g status-left-length 30
set -g status-right-length 50
set -g window-status-separator ""
set -gw automatic-rename on
set -gw automatic-rename-format '#{b:pane_current_path}'
# #{window_icon} is filled in by tmux-nerd-font-window-name (icons from
# tmux-nerd-font-window-name.yml); the label follows kitty's tab_bar.py. An
# editor shows the file from the title nvim sets ("<file> | <org/repo>", see
# nvim's astrocore custom_title), read straight from #{pane_title} so a buffer
# switch renames the tab at once; otherwise tab-label.sh prints the repo of the
# pane's cwd (an async #() job; it re-arms automatic-rename when the tab is
# stale, so a `cd` relabels without waiting for more pane output).
set -gw automatic-rename-format '#{window_icon} #{=/27/…:#{?#{&&:#{m/r:^(n?vim|vim|nvim-qt|hx|helix)$,#{pane_current_command}},#{m/r:^[^/|]+ \| ,#{pane_title}}},#{s/ \| .*$//:pane_title},#(~/.config/tmux/tab-label.sh #{q:pane_current_path} #{window_id})}}'
set -g set-titles on
set -g set-titles-string '#h:#W'
# Theme
set -g status-style "bg=default,fg=default"
set -g status-left "#[fg=black,bg=blue,bold] #S #[bg=default] "
set -g status-right "#[fg=blue]#{?pane_in_mode,COPY ,}#{?client_prefix,PREFIX ,}#{?window_zoomed_flag,ZOOM ,}#[fg=brightblack]#h "
set -g window-status-format "#[fg=brightblack] #I:#W "
set -g window-status-current-format "#[fg=blue,bold] #I:#W "
# Theme — kitty's powerline/angled tab bar (kitty.conf + the Omarchy kitty
# template): the current window is an accent-tinted plate with the accent as
# its text, the rest sit flush with the background in muted text. Colors are
# cyberdream defaults, overridden per Omarchy theme by tmux.conf rendered from
# ~/.config/omarchy/themed/tmux.conf.tpl.
set -g @tab-bg "#16181a"
set -g @tab-fg "#7b8496"
set -g @tab-active-bg "#243348"
set -g @tab-active-fg "#5ea1ff"
source-file -q ~/.local/state/omarchy/current/theme/tmux.conf
set -g status-style "bg=default,fg=#{@tab-fg}"
# bg=default inside a tab format means "the window-status-*-style bg", not the
# terminal's, so these must stay default for the tabs to be transparent. Set
# explicitly: a config reload never clears a value a removed plugin left
# behind (tmux-dotbar painted window-status-style bg=#0B0E14).
set -g window-status-style default
set -g window-status-current-style default
set -g window-status-last-style default
set -g window-status-activity-style default
set -g window-status-bell-style default
# Tabs start right after the session pill (status-justify left; a reload
# would otherwise keep a stale value such as dotbar's absolute-centre), and
# the pill's arrow points into the first tab's plate.
set -g status-justify left
set -g status-left "#[fg=#{@tab-bg},bg=#{@tab-active-fg},bold] #S #[fg=#{@tab-active-fg},nobold]#{?#{==:#{active_window_index},#{base-index}},#[bg=#{@tab-active-bg}],#[bg=default]}"
set -g status-right "#[fg=#{@tab-active-fg}]#{?pane_in_mode,COPY ,}#{?client_prefix,PREFIX ,}#{?window_zoomed_flag,ZOOM ,}#[fg=#{@tab-fg}]#h "
# Inactive tabs are bg=default so the terminal's transparency shows through,
# as in kitty (tab_bar_background none). kitty's separator rule: a solid
#  into a differently colored neighbour, thin  between two inactive
# tabs, none after the last. The arrow into the current tab is painted in
# @tab-bg, the window background; Ghostty's background-opacity-cells gives it
# the same opacity as the window, so it is indistinguishable from it. (Plain
#  is one of Ghostty's built-in sprites and fills the whole cell even
# with adjust-cell-height; inverse glyphs such as  come from the font
# and leave gaps.)
set -g window-status-format "#[fg=#{@tab-fg},bg=default] #I #W #{?next_window_active,#[fg=#{@tab-bg}#,bg=#{@tab-active-bg}],#{?window_end_flag,,}}"
set -g window-status-current-format "#[fg=#{@tab-active-fg},bg=#{@tab-active-bg},bold] #I #W #[fg=#{@tab-active-bg},bg=default,nobold]"
set -g pane-border-style "fg=brightblack"
set -g pane-active-border-style "fg=blue"
set -g message-style "bg=default,fg=blue"
set -g message-command-style "bg=default,fg=blue"
set -g mode-style "bg=blue,fg=black"
set -g pane-active-border-style "fg=#{@tab-active-fg}"
set -g message-style "bg=default,fg=#{@tab-active-fg}"
set -g message-command-style "bg=default,fg=#{@tab-active-fg}"
set -g mode-style "bg=#{@tab-active-bg},fg=#{@tab-active-fg}"
setw -g clock-mode-colour blue
# Plugins (tpm, cloned by .chezmoiexternal.toml). prefix + I installs,
# prefix + U updates, prefix + alt + u removes unlisted ones.
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'vaaleyard/tmux-dotbar'
set -g @plugin 'joshmedeski/tmux-nerd-font-window-name'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @plugin 'omerxx/tmux-sessionx'
# sessionx: fuzzy session switcher/creator on prefix + o (Ghostty
# ctrl+shift+o). A query with no match goes to zoxide; uses fzf --tmux.
set -g @sessionx-bind 'o'
set -g @sessionx-zoxide-mode 'on'
set -g @sessionx-fzf-builtin-tmux 'on'
# Persistence: continuum saves every 10 min (resurrect: prefix + C-s save,
# prefix + C-r restore) and restores the last save when the server starts,
# i.e. the first Ghostty window after login or reboot.
set -g @resurrect-capture-pane-contents 'on'
set -g @continuum-save-interval '10'
set -g @continuum-restore 'on'
# Keep at the very bottom.
run '~/.config/tmux/plugins/tpm/tpm'