tmux: Add `extraConfigBeforePlugins` to `tmux.config`

Adds the possibility to add config before the plugins are loaded
This commit is contained in:
Gabriel Nützi 2023-11-17 19:01:55 +01:00
parent 898a1cef2d
commit a163b13a28
3 changed files with 117 additions and 70 deletions

View File

@ -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)
]);
}

View File

@ -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 #
# --------------------------------------------- #

View File

@ -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}
'';
};
}