diff --git a/modules/programs/tmux.nix b/modules/programs/tmux.nix index da4c94d6..3c6e389b 100644 --- a/modules/programs/tmux.nix +++ b/modules/programs/tmux.nix @@ -1,9 +1,16 @@ -{ config, lib, pkgs, ... }: -with lib; -let +{ + config, + lib, + pkgs, + ... +}: +with lib; let cfg = config.programs.tmux; - pluginName = p: if types.package.check p then p.pname else p.plugin.pname; + pluginName = p: + if types.package.check p + then p.pname + else p.plugin.pname; pluginModule = types.submodule { options = { @@ -26,7 +33,10 @@ let defaultTerminal = "screen"; defaultShell = null; - boolToStr = value: if value then "on" else "off"; + boolToStr = value: + if value + then "on" + else "off"; tmuxConf = '' ${optionalString cfg.sensibleOnTop '' @@ -54,38 +64,42 @@ let set -g mode-keys ${cfg.keyMode} ${optionalString - (cfg.keyMode == "vi" && cfg.customPaneNavigationAndResize) '' - bind -N "Select pane to the left of the active pane" h select-pane -L - bind -N "Select pane below the active pane" j select-pane -D - bind -N "Select pane above the active pane" k select-pane -U - bind -N "Select pane to the right of the active pane" l select-pane -R + (cfg.keyMode == "vi" && cfg.customPaneNavigationAndResize) '' + bind -N "Select pane to the left of the active pane" h select-pane -L + bind -N "Select pane below the active pane" j select-pane -D + bind -N "Select pane above the active pane" k select-pane -U + bind -N "Select pane to the right of the active pane" l select-pane -R - bind -r -N "Resize the pane left by ${toString cfg.resizeAmount}" \ - H resize-pane -L ${toString cfg.resizeAmount} - bind -r -N "Resize the pane down by ${toString cfg.resizeAmount}" \ - J resize-pane -D ${toString cfg.resizeAmount} - bind -r -N "Resize the pane up by ${toString cfg.resizeAmount}" \ - K resize-pane -U ${toString cfg.resizeAmount} - bind -r -N "Resize the pane right by ${toString cfg.resizeAmount}" \ - L resize-pane -R ${toString cfg.resizeAmount} - ''} - - ${if cfg.prefix != null then '' - # rebind main key: ${cfg.prefix} - unbind C-${defaultShortcut} - set -g prefix ${cfg.prefix} - bind -N "Send the prefix key through to the application" \ - ${cfg.prefix} send-prefix - '' else - optionalString (cfg.shortcut != defaultShortcut) '' - # rebind main key: C-${cfg.shortcut} - unbind C-${defaultShortcut} - set -g prefix C-${cfg.shortcut} - bind -N "Send the prefix key through to the application" \ - ${cfg.shortcut} send-prefix - bind C-${cfg.shortcut} last-window + bind -r -N "Resize the pane left by ${toString cfg.resizeAmount}" \ + H resize-pane -L ${toString cfg.resizeAmount} + bind -r -N "Resize the pane down by ${toString cfg.resizeAmount}" \ + J resize-pane -D ${toString cfg.resizeAmount} + bind -r -N "Resize the pane up by ${toString cfg.resizeAmount}" \ + K resize-pane -U ${toString cfg.resizeAmount} + bind -r -N "Resize the pane right by ${toString cfg.resizeAmount}" \ + L resize-pane -R ${toString cfg.resizeAmount} ''} + ${ + if cfg.prefix != null + then '' + # rebind main key: ${cfg.prefix} + unbind C-${defaultShortcut} + set -g prefix ${cfg.prefix} + bind -N "Send the prefix key through to the application" \ + ${cfg.prefix} send-prefix + '' + else + optionalString (cfg.shortcut != defaultShortcut) '' + # rebind main key: C-${cfg.shortcut} + unbind C-${defaultShortcut} + set -g prefix C-${cfg.shortcut} + bind -N "Send the prefix key through to the application" \ + ${cfg.shortcut} send-prefix + bind C-${cfg.shortcut} last-window + '' + } + ${optionalString cfg.disableConfirmationPrompt '' bind-key -N "Kill the current window" & kill-window bind-key -N "Kill the current pane" x kill-pane @@ -93,7 +107,11 @@ let set -g mouse ${boolToStr cfg.mouse} setw -g aggressive-resize ${boolToStr cfg.aggressiveResize} - setw -g clock-mode-style ${if cfg.clock24 then "24" else "12"} + setw -g clock-mode-style ${ + if cfg.clock24 + then "24" + else "12" + } set -s escape-time ${toString cfg.escapeTime} set -g history-limit ${toString cfg.historyLimit} ''; @@ -104,8 +122,9 @@ let hasBadPluginName = p: !(hasPrefix "tmuxplugin" (pluginName p)); badPlugins = filter hasBadPluginName cfg.plugins; in { - assertion = badPlugins == [ ]; - message = ''Invalid tmux plugin (not prefixed with "tmuxplugins"): '' + assertion = badPlugins == []; + message = + ''Invalid tmux plugin (not prefixed with "tmuxplugins"): '' + concatMapStringsSep ", " pluginName badPlugins; }) ]; @@ -116,11 +135,16 @@ let # --------------------------------------------- # ${(concatMapStringsSep "\n\n" (p: '' - # ${pluginName p} - # --------------------- - ${p.extraConfig or ""} - run-shell ${if types.package.check p then p.rtp else p.plugin.rtp} - '') cfg.plugins)} + # ${pluginName p} + # --------------------- + ${p.extraConfig or ""} + run-shell ${ + if types.package.check p + then p.rtp + else p.plugin.rtp + } + '') + cfg.plugins)} # ============================================= # ''; }; @@ -206,7 +230,7 @@ in { keyMode = mkOption { default = defaultKeyMode; example = "vi"; - type = types.enum [ "emacs" "vi" ]; + type = types.enum ["emacs" "vi"]; description = "VI or Emacs style shortcuts."; }; @@ -300,7 +324,8 @@ in { plugins = mkOption { type = with types; - listOf (either package pluginModule) // { + listOf (either package pluginModule) + // { description = "list of plugin packages or submodules"; }; description = '' @@ -308,7 +333,7 @@ in { configuration. The sensible plugin, however, is defaulted to run at the top of your configuration. ''; - default = [ ]; + default = []; example = literalExpression '' with pkgs; [ tmuxPlugins.cpu @@ -331,12 +356,18 @@ in { config = mkIf cfg.enable (mkMerge [ { - home.packages = [ cfg.package ] + home.packages = + [cfg.package] ++ optional cfg.tmuxinator.enable pkgs.tmuxinator ++ optional cfg.tmuxp.enable pkgs.tmuxp; } - { xdg.configFile."tmux/tmux.conf".text = mkBefore tmuxConf; } + {xdg.configFile."tmux/tmux.conf".text = mkBefore tmuxConf;} + {xdg.configFile."tmux/tmux.conf".text = mkAfter cfg.extraConfig;} + + { + # xdg.configFile."tmux/tmux.conf".text = mkIf (cfg.extraConfigBeforePlugins != "") (mkBefore cfg.extraConfigBeforePlugins); + } (mkIf cfg.secureSocket { home.sessionVariables = { @@ -344,11 +375,6 @@ in { }; }) - { - xdg.configFile."tmux/tmux.conf".text = - mkAfter cfg.extraConfigBeforePlugins; - } - (mkIf (cfg.plugins != [ ]) configPlugins) - { xdg.configFile."tmux/tmux.conf".text = cfg.extraConfig; } + (mkIf (cfg.plugins != []) configPlugins) ]); } diff --git a/tests/modules/programs/tmux/extra-config-before-plugins.conf b/tests/modules/programs/tmux/extra-config-before-plugins.conf index f6d25fe8..3f34e894 100644 --- a/tests/modules/programs/tmux/extra-config-before-plugins.conf +++ b/tests/modules/programs/tmux/extra-config-before-plugins.conf @@ -1,15 +1,17 @@ # ============================================= # # Start with defaults from the Sensible plugin # # --------------------------------------------- # -run-shell @sensible_rtp@ +run-shell @tmuxplugin_sensible_rtp@ # ============================================= # set -g default-terminal "screen" set -g base-index 0 setw -g pane-base-index 0 +new-session - +bind -N "Split the pane into two, left and right" v split-window -h +bind -N "Split the pane into two, top and bottom" s split-window -v set -g status-keys emacs @@ -21,12 +23,12 @@ set -g mode-keys emacs -set -g mouse on -setw -g aggressive-resize off -setw -g clock-mode-style 12 +set -g mouse off +setw -g aggressive-resize on +setw -g clock-mode-style 24 set -s escape-time 500 set -g history-limit 2000 -set -g mouse off + # ============================================= # # Load plugins with Home Manager # # --------------------------------------------- # diff --git a/tests/modules/programs/tmux/extra-config-before-plugins.nix b/tests/modules/programs/tmux/extra-config-before-plugins.nix index b2f0e71a..2ffa58f8 100644 --- a/tests/modules/programs/tmux/extra-config-before-plugins.nix +++ b/tests/modules/programs/tmux/extra-config-before-plugins.nix @@ -1,28 +1,47 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; { config = { programs.tmux = { + aggressiveResize = true; + clock24 = true; enable = true; - mouse = true; - extraConfigBeforePlugins = '' - set -g mouse off - ''; + keyMode = "emacs"; + newSession = true; + reverseSplit = true; - plugins = with pkgs.tmuxPlugins; [ logging ]; + plugins = with pkgs.tmuxPlugins; [ + logging + ]; }; nixpkgs.overlays = [ (self: super: { - tmuxPlugins = super.tmuxPlugins // { - sensible = super.tmuxPlugins.sensible // { rtp = "@sensible_rtp@"; }; - }; + tmuxPlugins = + super.tmuxPlugins + // { + logging = + super.tmuxPlugins.logging + // { + rtp = "@tmuxplugin_logging_rtp@"; + }; + + sensible = + super.tmuxPlugins.sensible + // { + rtp = "@tmuxplugin_sensible_rtp@"; + }; + }; }) ]; nmt.script = '' assertFileExists home-files/.config/tmux/tmux.conf - assertFileContent home-files/.config/tmux/tmux.conf \ - ${./mouse-enabled.conf} + assertFileContent home-files/.config/tmux/tmux.conf ${./emacs-with-plugins.conf} ''; }; }