Fold dotfiles-nixos into this repository #1
43
.claude/tasks/0006-tmux-module.md
Normal file
43
.claude/tasks/0006-tmux-module.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
---
|
||||||
|
spec: laptop-mvi
|
||||||
|
blocked-by: 0001-skeleton-and-building-host
|
||||||
|
---
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
A tmux `Module`, configured natively via home-manager, that reproduces the current terminal multiplexer exactly: the existing `tmux.conf` text (under `reference/home/.config/tmux/`) inlined verbatim, with no plugin manager needed.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [x] A tmux `Module` (following the `Enable convention`) is enabled on `neogaia` and configured natively via home-manager.
|
||||||
|
- [x] The existing `tmux.conf` text is inlined verbatim, producing an identical configuration to today.
|
||||||
|
- [x] No tmux plugin manager is used.
|
||||||
|
- [x] The `neogaia` toplevel still builds with the tmux `Module` enabled.
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
**Approach — option translation ("the nix way") instead of byte-verbatim inlining.**
|
||||||
|
On the operator's explicit call ("I would prefer to do things the nix way. It's okay if the config file doesn't match"), the settings home-manager's `programs.tmux` exposes as options are set as options (`prefix`, `keyMode`, `mouse`, `baseIndex`, `clock24`, `escapeTime`, `historyLimit`, `terminal`), and only the settings it has *no* option for are inlined verbatim, read from `modules/tmux/extra.conf` via `builtins.readFile`.
|
||||||
|
The generated `~/.config/tmux/tmux.conf` is therefore **behaviourally** identical to today, not byte-identical: home-manager prepends its own option-derived lines.
|
||||||
|
This was preferred over `xdg.configFile.source = ./tmux.conf` (which would have been byte-identical) after weighing both.
|
||||||
|
Verified end-to-end by having a live tmux binary parse the generated config: `prefix=C-Space base-index=1 mode-keys=vi clipboard=on hist=10000 clock=24`, zero parse errors.
|
||||||
|
|
||||||
|
**`clock24 = true` is required, not cosmetic.**
|
||||||
|
home-manager always emits `clock-mode-style`; `true` → 24, which matches tmux's own compiled default (what the reference config, which never sets it, gets today).
|
||||||
|
Leaving it at the module default (`false`) would have *forced* a 12-hour clock — a real deviation.
|
||||||
|
|
||||||
|
**Pane navigation stays in `extra.conf`.**
|
||||||
|
home-manager's `customPaneNavigationAndResize` option would emit the `h/j/k/l select-pane` binds, but it *also* adds `H/J/K/L` resize binds the reference config does not have.
|
||||||
|
To stay faithful, the `h/j/k/l` binds are inlined in `extra.conf` and the option is left off.
|
||||||
|
|
||||||
|
**`secureSocket` left at the home-manager default (`true`).**
|
||||||
|
The tmux socket lives under `/run` rather than `/tmp`; it does not survive logout.
|
||||||
|
This differs from stock tmux behaviour and was accepted deliberately.
|
||||||
|
|
||||||
|
**Comments in `extra.conf` rewritten to the project convention.**
|
||||||
|
The reference `tmux.conf` comments justify choices against alternatives, speculate about future setups, and reference other files — all disallowed by the CLAUDE.md comment convention.
|
||||||
|
Since `extra.conf` is authored repo config, its comments were tightened to describe only current behaviour; every tmux directive is preserved verbatim, so behaviour is unchanged.
|
||||||
|
|
||||||
|
**Version-sensitivity (not a defect today).**
|
||||||
|
`programs.tmux.sensibleOnTop` defaults to `false` at the pinned home-manager rev, so no `tmux-sensible` plugin is injected and the "no plugin manager" criterion holds.
|
||||||
|
A future home-manager bump that flipped that default would silently pull the plugin in.
|
||||||
@@ -39,6 +39,9 @@
|
|||||||
modules.fish.enable = true;
|
modules.fish.enable = true;
|
||||||
modules.fish.defaultShell = true;
|
modules.fish.defaultShell = true;
|
||||||
|
|
||||||
|
# tmux as the terminal multiplexer.
|
||||||
|
modules.tmux.enable = true;
|
||||||
|
|
||||||
# Locale preferences for the base system.
|
# Locale preferences for the base system.
|
||||||
time.timeZone = "America/New_York";
|
time.timeZone = "America/New_York";
|
||||||
i18n.defaultLocale = "en_GB.UTF-8";
|
i18n.defaultLocale = "en_GB.UTF-8";
|
||||||
|
|||||||
49
modules/tmux/extra.conf
Normal file
49
modules/tmux/extra.conf
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Copy-mode selections land in the system clipboard via the terminal's own
|
||||||
|
# OSC52 escape sequence.
|
||||||
|
set -g set-clipboard on
|
||||||
|
|
||||||
|
bind -T copy-mode-vi v send -X begin-selection
|
||||||
|
bind -T copy-mode-vi y send -X copy-selection-and-cancel
|
||||||
|
bind -T copy-mode-vi MouseDragEnd1Pane send -X copy-selection-and-cancel
|
||||||
|
|
||||||
|
# \ splits the pane side-by-side, - splits it stacked; both open the new pane
|
||||||
|
# in the current pane's directory, as does c for a new window.
|
||||||
|
unbind %
|
||||||
|
unbind '"'
|
||||||
|
bind \\ split-window -h -c "#{pane_current_path}"
|
||||||
|
bind - split-window -v -c "#{pane_current_path}"
|
||||||
|
bind c new-window -c "#{pane_current_path}"
|
||||||
|
|
||||||
|
bind h select-pane -L
|
||||||
|
bind j select-pane -D
|
||||||
|
bind k select-pane -U
|
||||||
|
bind l select-pane -R
|
||||||
|
|
||||||
|
set -g renumber-windows on
|
||||||
|
|
||||||
|
bind r source-file ~/.config/tmux/tmux.conf \; display-message "tmux.conf reloaded"
|
||||||
|
|
||||||
|
# Advertise RGB (true-color) capability for every terminal type.
|
||||||
|
set -ag terminal-overrides ",*:RGB"
|
||||||
|
|
||||||
|
# monitor-bell flags a background window in the status bar when it rings the
|
||||||
|
# terminal bell while unfocused. bell-action=none suppresses the actual BEL
|
||||||
|
# (no beep or flash); the per-window status highlight is independent of it.
|
||||||
|
setw -g monitor-bell on
|
||||||
|
set -g bell-action none
|
||||||
|
|
||||||
|
# Minimal status bar (session name + window list only), styled with Nord
|
||||||
|
# colours.
|
||||||
|
set -g status-position bottom
|
||||||
|
set -g status-style "bg=#2E3440,fg=#D8DEE9"
|
||||||
|
set -g status-left " #S "
|
||||||
|
set -g status-left-length 20
|
||||||
|
set -g status-right ""
|
||||||
|
setw -g window-status-current-style "bg=#88C0D0,fg=#2E3440,bold"
|
||||||
|
setw -g window-status-current-format " #I:#W "
|
||||||
|
setw -g window-status-format " #I:#W "
|
||||||
|
setw -g window-status-style "fg=#4C566A"
|
||||||
|
setw -g window-status-bell-style "bg=#BF616A,fg=#2E3440,bold"
|
||||||
|
|
||||||
|
set -g pane-border-style "fg=#3B4252"
|
||||||
|
set -g pane-active-border-style "fg=#88C0D0"
|
||||||
33
modules/tmux/tmux.nix
Normal file
33
modules/tmux/tmux.nix
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
# tmux for the primary user, configured natively through home-manager. The
|
||||||
|
# settings home-manager exposes as options are set here; every setting it has
|
||||||
|
# no option for is read verbatim from ./extra.conf. No tmux plugin manager is
|
||||||
|
# used.
|
||||||
|
let
|
||||||
|
cfg = config.modules.tmux;
|
||||||
|
user = config.user.name;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.modules.tmux.enable = lib.mkEnableOption "tmux, configured via home-manager";
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home-manager.users.${user}.programs.tmux = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
prefix = "C-Space";
|
||||||
|
keyMode = "vi";
|
||||||
|
mouse = true;
|
||||||
|
baseIndex = 1; # windows and panes count from 1.
|
||||||
|
clock24 = true; # 24-hour clock in the clock-mode overlay.
|
||||||
|
escapeTime = 10; # short Esc delay so exiting insert mode in nvim isn't laggy.
|
||||||
|
historyLimit = 10000;
|
||||||
|
terminal = "tmux-256color";
|
||||||
|
|
||||||
|
extraConfig = builtins.readFile ./extra.conf;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user