Skip to content

Commit f3cf1e5

Browse files
committed
ghostty tmux
1 parent e65d680 commit f3cf1e5

2 files changed

Lines changed: 147 additions & 2 deletions

File tree

modules/shell/ghostty.nix

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
shell-integration = "detect";
3939
shell-integration-features = "cursor,sudo,title,ssh-env,ssh-terminfo";
4040

41+
# Auto-attach to tmux. Runs via /bin/sh -c. -A = attach if server
42+
# exists (continuum will have restored saved sessions), otherwise
43+
# start a new one.
44+
command = "tmux new -A";
45+
4146
# Clipboard
4247
clipboard-write = "allow";
4348
clipboard-read = "allow";

modules/shell/tmux.nix

Lines changed: 142 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
{ den, ... }:
22
{
33
den.aspects.tmux.homeManager =
4-
{ pkgs, ... }:
4+
{ config, pkgs, ... }:
5+
let
6+
c = config.lib.stylix.colors;
7+
in
58
{
69
programs.tmux = {
710
enable = true;
@@ -15,6 +18,143 @@
1518
terminal = "tmux-256color";
1619
shell = "${pkgs.zsh}/bin/zsh";
1720
historyLimit = 10000;
21+
22+
# Declarative plugins (no tpm needed; each is packaged in nixpkgs)
23+
plugins = [
24+
{ plugin = pkgs.tmuxPlugins.sensible; }
25+
{ plugin = pkgs.tmuxPlugins.yank; }
26+
{ plugin = pkgs.tmuxPlugins.better-mouse-mode; }
27+
{
28+
plugin = pkgs.tmuxPlugins.resurrect;
29+
extraConfig = ''
30+
set -g @resurrect-strategy-nvim 'session'
31+
set -g @resurrect-processes 'ssh'
32+
set -g @resurrect-capture-pane-contents 'on'
33+
'';
34+
}
35+
{
36+
plugin = pkgs.tmuxPlugins.continuum;
37+
extraConfig = ''
38+
set -g @continuum-restore 'on'
39+
set -g @continuum-save-interval '15'
40+
'';
41+
}
42+
];
43+
44+
extraConfig = ''
45+
# ---- Status bar (kitty tab-bar style, eldritch via stylix) ----
46+
# Backdrop is the deep "default" background (transparent) so the
47+
# / half-block separators blend into the terminal's bg.
48+
set -g status-style bg=default,fg=#${c.base05}
49+
set -g status-left-length 40
50+
set -g status-right-length 60
51+
52+
# Window status — modelled on kitty's tab_bar:
53+
# inactive: slate ears + cyan index:name on transparent bg
54+
# active: green ears + dark index:name on green (like active tab)
55+
setw -g window-status-format \
56+
'#[fg=#${c.base01},bg=default] #[fg=#${c.base0C},bg=default] #{window_index}:#{window_name} #[fg=#${c.base01},bg=default] '
57+
setw -g window-status-current-format \
58+
'#[fg=#${c.base0B},bg=default] #[fg=#${c.base00},bg=#${c.base0B}] #{window_index}:#{window_name} #[fg=#${c.base0B},bg=default] '
59+
setw -g window-status-separator '''
60+
61+
# A subtle mark for windows with activity/bell
62+
setw -g window-status-activity-style fg=#${c.base0E},bg=#${c.base01}
63+
setw -g window-status-bell-style fg=#${c.base08},bg=#${c.base01}
64+
65+
# Pane border
66+
set -g pane-border-style fg=#${c.base02}
67+
set -g pane-active-border-style fg=#${c.base0C}
68+
69+
# Message / command prompt
70+
set -g message-style bg=#${c.base0C},fg=#${c.base00}
71+
set -g message-command-style bg=#${c.base0C},fg=#${c.base00}
72+
73+
# Mode (copy-mode) indicator
74+
set -g mode-style bg=#${c.base0C},fg=#${c.base00}
75+
76+
# Refresh every 5s
77+
set -g status-interval 5
78+
79+
# Left: session name in a green "tab"
80+
set -g status-left '#[fg=#${c.base00} bg=#${c.base0B}] #S #[fg=#${c.base0B},bg=default]'
81+
# Right: time in a cyan "tab"
82+
set -g status-right '#[fg=#${c.base0C},bg=default] %H:%M '
83+
set -g status-right-length 30
84+
85+
# -------------------------------------------------
86+
# Keybindings
87+
# -------------------------------------------------
88+
89+
# Reload config
90+
bind R source-file ~/.config/tmux/tmux.conf \; display-message 'tmux.conf reloaded'
91+
92+
# Splits (open in current pane directory)
93+
# v = vertical split (side-by-side), b = horizontal split (stacked)
94+
bind v split-window -h -c '#{pane_current_path}'
95+
bind b split-window -v -c '#{pane_current_path}'
96+
97+
# Terminal windows
98+
bind c new-window -c '#{pane_current_path}'
99+
100+
# Kill pane without prompt
101+
bind X kill-pane
102+
103+
# Swap panes
104+
bind '{' swap-pane -U
105+
bind '}' swap-pane -D
106+
107+
# Zoom
108+
bind z resize-pane -Z
109+
bind m resize-pane -Z
110+
111+
# Resize bindings (shift+hjkl)
112+
bind H resize-pane -L 5
113+
bind J resize-pane -D 5
114+
bind K resize-pane -U 5
115+
bind L resize-pane -R 5
116+
117+
# Pane navigation via vim keys
118+
bind h select-pane -L
119+
bind j select-pane -D
120+
bind k select-pane -U
121+
bind l select-pane -R
122+
123+
# Interactive resize mode: prefix+r, then hjkl / arrows to resize,
124+
# q / Esc / Enter to exit back to normal mode
125+
bind r set -g key-table resize
126+
bind -T resize h resize-pane -L 5
127+
bind -T resize j resize-pane -D 5
128+
bind -T resize k resize-pane -U 5
129+
bind -T resize l resize-pane -R 5
130+
bind -T resize Left resize-pane -L 5
131+
bind -T resize Down resize-pane -D 5
132+
bind -T resize Up resize-pane -U 5
133+
bind -T resize Right resize-pane -R 5
134+
bind -T resize q set -g key-table root
135+
bind -T resize Escape set -g key-table root
136+
bind -T resize Enter set -g key-table root
137+
138+
# Incremental resize (repeatable): prefix+- / prefix++
139+
bind -r '-' resize-pane -L 5
140+
bind -r '+' resize-pane -R 5
141+
142+
# Detach
143+
bind d detach-client
144+
145+
# Session management
146+
bind t command-prompt -I '#S' 'rename-session -- "%%"'
147+
bind '$' command-prompt -I '#S' 'rename-session -- "%%"'
148+
bind ',' command-prompt -I '#W' 'rename-window -- "%%"'
149+
150+
# Pane navigation across windows (with prefix)
151+
bind C-h select-window -t :- & select-pane -L
152+
bind C-j select-window -t :+ & select-pane -D
153+
154+
# Move window
155+
bind '<' swap-window -t -1
156+
bind '>' swap-window -t +1
157+
'';
18158
};
19159
};
20-
}
160+
}

0 commit comments

Comments
 (0)