1 { config, pkgs, lib, ... }:
4 inherit (lib) mkOption mkIf types optionalString;
6 cfg = config.programs.tmux;
8 defaultKeyMode = "emacs";
10 defaultShortcut = "b";
11 defaultTerminal = "screen";
13 boolToStr = value: if value then "on" else "off";
16 set -g default-terminal "${cfg.terminal}"
17 set -g base-index ${toString cfg.baseIndex}
18 setw -g pane-base-index ${toString cfg.baseIndex}
19 set -g history-limit ${toString cfg.historyLimit}
21 ${optionalString cfg.newSession "new-session"}
23 ${optionalString cfg.reverseSplit ''
24 bind v split-window -h
25 bind s split-window -v
28 set -g status-keys ${cfg.keyMode}
29 set -g mode-keys ${cfg.keyMode}
31 ${optionalString (cfg.keyMode == "vi" && cfg.customPaneNavigationAndResize) ''
37 bind -r H resize-pane -L ${toString cfg.resizeAmount}
38 bind -r J resize-pane -D ${toString cfg.resizeAmount}
39 bind -r K resize-pane -U ${toString cfg.resizeAmount}
40 bind -r L resize-pane -R ${toString cfg.resizeAmount}
43 ${optionalString (cfg.shortcut != defaultShortcut) ''
44 # rebind main key: C-${cfg.shortcut}
45 unbind C-${defaultShortcut}
46 set -g prefix C-${cfg.shortcut}
47 bind ${cfg.shortcut} send-prefix
48 bind C-${cfg.shortcut} last-window
51 setw -g aggressive-resize ${boolToStr cfg.aggressiveResize}
52 setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"}
53 set -s escape-time ${toString cfg.escapeTime}
55 ${cfg.extraConfigBeforePlugins}
57 ${lib.optionalString (cfg.plugins != []) ''
59 ${lib.concatMapStringsSep "\n" (x: "run-shell ${x.rtp}") cfg.plugins}
75 description = "Whenever to configure {command}`tmux` system-wide.";
76 relatedPackages = [ "tmux" ];
79 aggressiveResize = mkOption {
83 Resize the window to the size of the smallest session for which it is the current window.
87 baseIndex = mkOption {
91 description = "Base index for windows and panes.";
97 description = "Use 24 hour clock.";
100 customPaneNavigationAndResize = mkOption {
103 description = "Override the hjkl and HJKL bindings for pane navigation and resizing in VI mode.";
106 escapeTime = mkOption {
110 description = "Time in milliseconds for which tmux waits after an escape is input.";
113 extraConfigBeforePlugins = mkOption {
116 Additional contents of /etc/tmux.conf, to be run before sourcing plugins.
121 extraConfig = mkOption {
124 Additional contents of /etc/tmux.conf, to be run after sourcing plugins.
129 historyLimit = mkOption {
133 description = "Maximum number of lines held in window history.";
137 default = defaultKeyMode;
139 type = types.enum [ "emacs" "vi" ];
140 description = "VI or Emacs style shortcuts.";
143 newSession = mkOption {
146 description = "Automatically spawn a session if trying to attach and none are running.";
149 reverseSplit = mkOption {
152 description = "Reverse the window split shortcuts.";
155 resizeAmount = mkOption {
156 default = defaultResize;
159 description = "Number of lines/columns when resizing.";
162 shortcut = mkOption {
163 default = defaultShortcut;
166 description = "Ctrl following by this key is used as the main shortcut.";
169 terminal = mkOption {
170 default = defaultTerminal;
171 example = "screen-256color";
174 Set the $TERM variable. Use tmux-direct if italics or 24bit true color
179 secureSocket = mkOption {
183 Store tmux socket under /run, which is more secure than /tmp, but as a
184 downside it doesn't survive user logout.
190 type = types.listOf types.package;
191 description = "List of plugins to install.";
192 example = lib.literalExpression "[ pkgs.tmuxPlugins.nord ]";
195 withUtempter = mkOption {
197 Whether to enable libutempter for tmux.
198 This is required so that tmux can write to /var/run/utmp (which can be queried with `who` to display currently connected user sessions).
199 Note, this will add a guid wrapper for the group utmp!
207 ###### implementation
209 config = mkIf cfg.enable {
211 etc."tmux.conf".text = tmuxConf;
213 systemPackages = [ pkgs.tmux ] ++ cfg.plugins;
216 TMUX_TMPDIR = lib.optional cfg.secureSocket ''''${XDG_RUNTIME_DIR:-"/run/user/$(id -u)"}'';
219 security.wrappers = mkIf cfg.withUtempter {
221 source = "${pkgs.libutempter}/lib/utempter/utempter";
231 (lib.mkRenamedOptionModule [ "programs" "tmux" "extraTmuxConf" ] [ "programs" "tmux" "extraConfig" ])
234 meta.maintainers = with lib.maintainers; [ hxtmdev ];