From 898a1cef2df1c2869b541aca47542d5bb675d863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20N=C3=BCtzi?= Date: Fri, 17 Nov 2023 18:29:27 +0100 Subject: [PATCH 1/2] tmux: Add `extraConfigBeforePlugins` to `tmux.config` Adds the possibility to add config before the plugins are loaded --- modules/programs/tmux.nix | 23 +++++++---- tests/modules/programs/tmux/default.nix | 1 + .../tmux/extra-config-before-plugins.conf | 39 +++++++++++++++++++ .../tmux/extra-config-before-plugins.nix | 28 +++++++++++++ 4 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 tests/modules/programs/tmux/extra-config-before-plugins.conf create mode 100644 tests/modules/programs/tmux/extra-config-before-plugins.nix diff --git a/modules/programs/tmux.nix b/modules/programs/tmux.nix index b68fd8d5..da4c94d6 100644 --- a/modules/programs/tmux.nix +++ b/modules/programs/tmux.nix @@ -1,9 +1,6 @@ { config, lib, pkgs, ... }: - with lib; - let - cfg = config.programs.tmux; pluginName = p: if types.package.check p then p.pname else p.plugin.pname; @@ -127,7 +124,6 @@ let # ============================================= # ''; }; - in { options = { programs.tmux = { @@ -191,6 +187,15 @@ in { ''; }; + extraConfigBeforePlugins = mkOption { + type = types.lines; + default = ""; + description = '' + Additional configuration to add to + {file}`tmux.conf` before the plugins. + ''; + }; + historyLimit = mkOption { default = 2000; example = 5000; @@ -324,7 +329,7 @@ in { }; }; - config = mkIf cfg.enable (mkMerge ([ + config = mkIf cfg.enable (mkMerge [ { home.packages = [ cfg.package ] ++ optional cfg.tmuxinator.enable pkgs.tmuxinator @@ -332,7 +337,6 @@ in { } { xdg.configFile."tmux/tmux.conf".text = mkBefore tmuxConf; } - { xdg.configFile."tmux/tmux.conf".text = mkAfter cfg.extraConfig; } (mkIf cfg.secureSocket { home.sessionVariables = { @@ -340,6 +344,11 @@ in { }; }) + { + xdg.configFile."tmux/tmux.conf".text = + mkAfter cfg.extraConfigBeforePlugins; + } (mkIf (cfg.plugins != [ ]) configPlugins) - ])); + { xdg.configFile."tmux/tmux.conf".text = cfg.extraConfig; } + ]); } diff --git a/tests/modules/programs/tmux/default.nix b/tests/modules/programs/tmux/default.nix index 979774a7..7370c8d0 100644 --- a/tests/modules/programs/tmux/default.nix +++ b/tests/modules/programs/tmux/default.nix @@ -8,4 +8,5 @@ tmux-shortcut-without-prefix = ./shortcut-without-prefix.nix; tmux-prefix = ./prefix.nix; tmux-mouse-enabled = ./mouse-enabled.nix; + tmux-extra-config-before-plugins = ./extra-config-before-plugins.nix; } diff --git a/tests/modules/programs/tmux/extra-config-before-plugins.conf b/tests/modules/programs/tmux/extra-config-before-plugins.conf new file mode 100644 index 00000000..f6d25fe8 --- /dev/null +++ b/tests/modules/programs/tmux/extra-config-before-plugins.conf @@ -0,0 +1,39 @@ +# ============================================= # +# Start with defaults from the Sensible plugin # +# --------------------------------------------- # +run-shell @sensible_rtp@ +# ============================================= # + +set -g default-terminal "screen" +set -g base-index 0 +setw -g pane-base-index 0 + + + + + +set -g status-keys emacs +set -g mode-keys emacs + + + + + + + +set -g mouse on +setw -g aggressive-resize off +setw -g clock-mode-style 12 +set -s escape-time 500 +set -g history-limit 2000 +set -g mouse off +# ============================================= # +# Load plugins with Home Manager # +# --------------------------------------------- # + +# tmuxplugin-logging +# --------------------- + +run-shell @tmuxplugin_logging_rtp@ + +# ============================================= # diff --git a/tests/modules/programs/tmux/extra-config-before-plugins.nix b/tests/modules/programs/tmux/extra-config-before-plugins.nix new file mode 100644 index 00000000..b2f0e71a --- /dev/null +++ b/tests/modules/programs/tmux/extra-config-before-plugins.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: +with lib; { + config = { + programs.tmux = { + enable = true; + mouse = true; + extraConfigBeforePlugins = '' + set -g mouse off + ''; + + plugins = with pkgs.tmuxPlugins; [ logging ]; + }; + + nixpkgs.overlays = [ + (self: super: { + tmuxPlugins = super.tmuxPlugins // { + sensible = super.tmuxPlugins.sensible // { rtp = "@sensible_rtp@"; }; + }; + }) + ]; + + nmt.script = '' + assertFileExists home-files/.config/tmux/tmux.conf + assertFileContent home-files/.config/tmux/tmux.conf \ + ${./mouse-enabled.conf} + ''; + }; +} From a163b13a289269cdde3f232f8fcaf11b0fb8a0f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20N=C3=BCtzi?= Date: Fri, 17 Nov 2023 19:01:55 +0100 Subject: [PATCH 2/2] tmux: Add `extraConfigBeforePlugins` to `tmux.config` Adds the possibility to add config before the plugins are loaded --- modules/programs/tmux.nix | 132 +++++++++++------- .../tmux/extra-config-before-plugins.conf | 14 +- .../tmux/extra-config-before-plugins.nix | 41 ++++-- 3 files changed, 117 insertions(+), 70 deletions(-) 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} ''; }; }