at 25.11-pre 6.7 kB view raw
1{ 2 config, 3 pkgs, 4 lib, 5 ... 6}: 7 8let 9 inherit (lib) 10 mkOption 11 mkPackageOption 12 mkIf 13 types 14 optionalString 15 ; 16 17 cfg = config.programs.tmux; 18 19 defaultKeyMode = "emacs"; 20 defaultResize = 5; 21 defaultShortcut = "b"; 22 defaultTerminal = "screen"; 23 24 boolToStr = value: if value then "on" else "off"; 25 26 tmuxConf = '' 27 set -g default-terminal "${cfg.terminal}" 28 set -g base-index ${toString cfg.baseIndex} 29 setw -g pane-base-index ${toString cfg.baseIndex} 30 set -g history-limit ${toString cfg.historyLimit} 31 32 ${optionalString cfg.newSession "new-session"} 33 34 ${optionalString cfg.reverseSplit '' 35 bind v split-window -h 36 bind s split-window -v 37 ''} 38 39 set -g status-keys ${cfg.keyMode} 40 set -g mode-keys ${cfg.keyMode} 41 42 ${optionalString (cfg.keyMode == "vi" && cfg.customPaneNavigationAndResize) '' 43 bind h select-pane -L 44 bind j select-pane -D 45 bind k select-pane -U 46 bind l select-pane -R 47 48 bind -r H resize-pane -L ${toString cfg.resizeAmount} 49 bind -r J resize-pane -D ${toString cfg.resizeAmount} 50 bind -r K resize-pane -U ${toString cfg.resizeAmount} 51 bind -r L resize-pane -R ${toString cfg.resizeAmount} 52 ''} 53 54 ${optionalString (cfg.shortcut != defaultShortcut) '' 55 # rebind main key: C-${cfg.shortcut} 56 unbind C-${defaultShortcut} 57 set -g prefix C-${cfg.shortcut} 58 bind ${cfg.shortcut} send-prefix 59 bind C-${cfg.shortcut} last-window 60 ''} 61 62 setw -g aggressive-resize ${boolToStr cfg.aggressiveResize} 63 setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"} 64 set -s escape-time ${toString cfg.escapeTime} 65 66 ${cfg.extraConfigBeforePlugins} 67 68 ${lib.optionalString (cfg.plugins != [ ]) '' 69 # Run plugins 70 ${lib.concatMapStringsSep "\n" (x: "run-shell ${x.rtp}") cfg.plugins} 71 72 ''} 73 74 ${cfg.extraConfig} 75 ''; 76 77in 78{ 79 ###### interface 80 81 options = { 82 programs.tmux = { 83 84 enable = mkOption { 85 type = types.bool; 86 default = false; 87 description = "Whenever to configure {command}`tmux` system-wide."; 88 relatedPackages = [ "tmux" ]; 89 }; 90 91 package = mkPackageOption pkgs "tmux" { }; 92 93 aggressiveResize = mkOption { 94 default = false; 95 type = types.bool; 96 description = '' 97 Resize the window to the size of the smallest session for which it is the current window. 98 ''; 99 }; 100 101 baseIndex = mkOption { 102 default = 0; 103 example = 1; 104 type = types.int; 105 description = "Base index for windows and panes."; 106 }; 107 108 clock24 = mkOption { 109 default = false; 110 type = types.bool; 111 description = "Use 24 hour clock."; 112 }; 113 114 customPaneNavigationAndResize = mkOption { 115 default = false; 116 type = types.bool; 117 description = "Override the hjkl and HJKL bindings for pane navigation and resizing in VI mode."; 118 }; 119 120 escapeTime = mkOption { 121 default = 500; 122 example = 0; 123 type = types.int; 124 description = "Time in milliseconds for which tmux waits after an escape is input."; 125 }; 126 127 extraConfigBeforePlugins = mkOption { 128 default = ""; 129 description = '' 130 Additional contents of /etc/tmux.conf, to be run before sourcing plugins. 131 ''; 132 type = types.lines; 133 }; 134 135 extraConfig = mkOption { 136 default = ""; 137 description = '' 138 Additional contents of /etc/tmux.conf, to be run after sourcing plugins. 139 ''; 140 type = types.lines; 141 }; 142 143 historyLimit = mkOption { 144 default = 2000; 145 example = 5000; 146 type = types.int; 147 description = "Maximum number of lines held in window history."; 148 }; 149 150 keyMode = mkOption { 151 default = defaultKeyMode; 152 example = "vi"; 153 type = types.enum [ 154 "emacs" 155 "vi" 156 ]; 157 description = "VI or Emacs style shortcuts."; 158 }; 159 160 newSession = mkOption { 161 default = false; 162 type = types.bool; 163 description = "Automatically spawn a session if trying to attach and none are running."; 164 }; 165 166 reverseSplit = mkOption { 167 default = false; 168 type = types.bool; 169 description = "Reverse the window split shortcuts."; 170 }; 171 172 resizeAmount = mkOption { 173 default = defaultResize; 174 example = 10; 175 type = types.int; 176 description = "Number of lines/columns when resizing."; 177 }; 178 179 shortcut = mkOption { 180 default = defaultShortcut; 181 example = "a"; 182 type = types.str; 183 description = "Ctrl following by this key is used as the main shortcut."; 184 }; 185 186 terminal = mkOption { 187 default = defaultTerminal; 188 example = "screen-256color"; 189 type = types.str; 190 description = '' 191 Set the $TERM variable. Use tmux-direct if italics or 24bit true color 192 support is needed. 193 ''; 194 }; 195 196 secureSocket = mkOption { 197 default = true; 198 type = types.bool; 199 description = '' 200 Store tmux socket under /run, which is more secure than /tmp, but as a 201 downside it doesn't survive user logout. 202 ''; 203 }; 204 205 plugins = mkOption { 206 default = [ ]; 207 type = types.listOf types.package; 208 description = "List of plugins to install."; 209 example = lib.literalExpression "[ pkgs.tmuxPlugins.nord ]"; 210 }; 211 212 withUtempter = mkOption { 213 description = '' 214 Whether to enable libutempter for tmux. 215 This is required so that tmux can write to /var/run/utmp (which can be queried with `who` to display currently connected user sessions). 216 Note, this will add a guid wrapper for the group utmp! 217 ''; 218 default = true; 219 type = types.bool; 220 }; 221 }; 222 }; 223 224 ###### implementation 225 226 config = mkIf cfg.enable { 227 environment = { 228 etc."tmux.conf".text = tmuxConf; 229 230 systemPackages = [ cfg.package ] ++ cfg.plugins; 231 232 variables = { 233 TMUX_TMPDIR = lib.optional cfg.secureSocket ''''${XDG_RUNTIME_DIR:-"/run/user/$(id -u)"}''; 234 }; 235 }; 236 security.wrappers = mkIf cfg.withUtempter { 237 utempter = { 238 source = "${pkgs.libutempter}/lib/utempter/utempter"; 239 owner = "root"; 240 group = "utmp"; 241 setuid = false; 242 setgid = true; 243 }; 244 }; 245 }; 246 247 imports = [ 248 (lib.mkRenamedOptionModule 249 [ "programs" "tmux" "extraTmuxConf" ] 250 [ "programs" "tmux" "extraConfig" ] 251 ) 252 ]; 253 254 meta.maintainers = with lib.maintainers; [ hxtmdev ]; 255}