mirror of
https://github.com/nix-community/home-manager
synced 2024-12-25 11:19:47 +01:00
9f9e277b60
These (and the `*MD` functions apart from `literalMD`) are now no-ops in nixpkgs and serve no purpose other than to add additional noise and potentially mislead people into thinking unmarked DocBook documentation will still be accepted. Note that if backporting changes including documentation to 23.05, the `mdDoc` calls will need to be re-added. To reproduce this commit, run: $ NIX_PATH=nixpkgs=flake:nixpkgs/e7e69199f0372364a6106a1e735f68604f4c5a25 \ nix shell nixpkgs#coreutils \ -c find . -name '*.nix' \ -exec nix run -- github:emilazy/nix-doc-munge/98dadf1f77351c2ba5dcb709a2a171d655f15099 \ --strip {} + $ ./format
345 lines
10 KiB
Nix
345 lines
10 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
cfg = config.programs.tmux;
|
|
|
|
pluginName = p: if types.package.check p then p.pname else p.plugin.pname;
|
|
|
|
pluginModule = types.submodule {
|
|
options = {
|
|
plugin = mkOption {
|
|
type = types.package;
|
|
description = "Path of the configuration file to include.";
|
|
};
|
|
|
|
extraConfig = mkOption {
|
|
type = types.lines;
|
|
description = "Additional configuration for the associated plugin.";
|
|
default = "";
|
|
};
|
|
};
|
|
};
|
|
|
|
defaultKeyMode = "emacs";
|
|
defaultResize = 5;
|
|
defaultShortcut = "b";
|
|
defaultTerminal = "screen";
|
|
defaultShell = null;
|
|
|
|
boolToStr = value: if value then "on" else "off";
|
|
|
|
tmuxConf = ''
|
|
${optionalString cfg.sensibleOnTop ''
|
|
# ============================================= #
|
|
# Start with defaults from the Sensible plugin #
|
|
# --------------------------------------------- #
|
|
run-shell ${pkgs.tmuxPlugins.sensible.rtp}
|
|
# ============================================= #
|
|
''}
|
|
set -g default-terminal "${cfg.terminal}"
|
|
set -g base-index ${toString cfg.baseIndex}
|
|
setw -g pane-base-index ${toString cfg.baseIndex}
|
|
${optionalString (cfg.shell != null) ''
|
|
# We need to set default-shell before calling new-session
|
|
set -g default-shell "${cfg.shell}"
|
|
''}
|
|
${optionalString cfg.newSession "new-session"}
|
|
|
|
${optionalString cfg.reverseSplit ''
|
|
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 ${cfg.keyMode}
|
|
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
|
|
|
|
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
|
|
''}
|
|
|
|
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"}
|
|
set -s escape-time ${toString cfg.escapeTime}
|
|
set -g history-limit ${toString cfg.historyLimit}
|
|
'';
|
|
|
|
configPlugins = {
|
|
assertions = [
|
|
(let
|
|
hasBadPluginName = p: !(hasPrefix "tmuxplugin" (pluginName p));
|
|
badPlugins = filter hasBadPluginName cfg.plugins;
|
|
in {
|
|
assertion = badPlugins == [ ];
|
|
message = ''Invalid tmux plugin (not prefixed with "tmuxplugins"): ''
|
|
+ concatMapStringsSep ", " pluginName badPlugins;
|
|
})
|
|
];
|
|
|
|
xdg.configFile."tmux/tmux.conf".text = ''
|
|
# ============================================= #
|
|
# Load plugins with Home Manager #
|
|
# --------------------------------------------- #
|
|
|
|
${(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)}
|
|
# ============================================= #
|
|
'';
|
|
};
|
|
|
|
in {
|
|
options = {
|
|
programs.tmux = {
|
|
aggressiveResize = mkOption {
|
|
default = false;
|
|
type = types.bool;
|
|
description = ''
|
|
Resize the window to the size of the smallest session for
|
|
which it is the current window.
|
|
'';
|
|
};
|
|
|
|
baseIndex = mkOption {
|
|
default = 0;
|
|
example = 1;
|
|
type = types.ints.unsigned;
|
|
description = "Base index for windows and panes.";
|
|
};
|
|
|
|
clock24 = mkOption {
|
|
default = false;
|
|
type = types.bool;
|
|
description = "Use 24 hour clock.";
|
|
};
|
|
|
|
customPaneNavigationAndResize = mkOption {
|
|
default = false;
|
|
type = types.bool;
|
|
description = ''
|
|
Override the hjkl and HJKL bindings for pane navigation and
|
|
resizing in VI mode.
|
|
'';
|
|
};
|
|
|
|
disableConfirmationPrompt = mkOption {
|
|
default = false;
|
|
type = types.bool;
|
|
description = ''
|
|
Disable confirmation prompt before killing a pane or window
|
|
'';
|
|
};
|
|
|
|
enable = mkEnableOption "tmux";
|
|
|
|
escapeTime = mkOption {
|
|
default = 500;
|
|
example = 0;
|
|
type = types.ints.unsigned;
|
|
description = ''
|
|
Time in milliseconds for which tmux waits after an escape is
|
|
input.
|
|
'';
|
|
};
|
|
|
|
extraConfig = mkOption {
|
|
type = types.lines;
|
|
default = "";
|
|
description = ''
|
|
Additional configuration to add to
|
|
{file}`tmux.conf`.
|
|
'';
|
|
};
|
|
|
|
historyLimit = mkOption {
|
|
default = 2000;
|
|
example = 5000;
|
|
type = types.ints.positive;
|
|
description = "Maximum number of lines held in window history.";
|
|
};
|
|
|
|
keyMode = mkOption {
|
|
default = defaultKeyMode;
|
|
example = "vi";
|
|
type = types.enum [ "emacs" "vi" ];
|
|
description = "VI or Emacs style shortcuts.";
|
|
};
|
|
|
|
mouse = mkEnableOption "mouse support";
|
|
|
|
newSession = mkOption {
|
|
default = false;
|
|
type = types.bool;
|
|
description = ''
|
|
Automatically spawn a session if trying to attach and none
|
|
are running.
|
|
'';
|
|
};
|
|
|
|
package = mkOption {
|
|
type = types.package;
|
|
default = pkgs.tmux;
|
|
defaultText = literalExpression "pkgs.tmux";
|
|
example = literalExpression "pkgs.tmux";
|
|
description = "The tmux package to install";
|
|
};
|
|
|
|
reverseSplit = mkOption {
|
|
default = false;
|
|
type = types.bool;
|
|
description = "Reverse the window split shortcuts.";
|
|
};
|
|
|
|
resizeAmount = mkOption {
|
|
default = defaultResize;
|
|
example = 10;
|
|
type = types.ints.positive;
|
|
description = "Number of lines/columns when resizing.";
|
|
};
|
|
|
|
sensibleOnTop = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = ''
|
|
Run the sensible plugin at the top of the configuration. It
|
|
is possible to override the sensible settings using the
|
|
{option}`programs.tmux.extraConfig` option.
|
|
'';
|
|
};
|
|
|
|
prefix = mkOption {
|
|
default = null;
|
|
example = "C-a";
|
|
type = types.nullOr types.str;
|
|
description = ''
|
|
Set the prefix key. Overrules the "shortcut" option when set.
|
|
'';
|
|
};
|
|
|
|
shortcut = mkOption {
|
|
default = defaultShortcut;
|
|
example = "a";
|
|
type = types.str;
|
|
description = ''
|
|
CTRL following by this key is used as the main shortcut.
|
|
'';
|
|
};
|
|
|
|
terminal = mkOption {
|
|
default = defaultTerminal;
|
|
example = "screen-256color";
|
|
type = types.str;
|
|
description = "Set the $TERM variable.";
|
|
};
|
|
|
|
shell = mkOption {
|
|
default = defaultShell;
|
|
example = "\${pkgs.zsh}/bin/zsh";
|
|
type = with types; nullOr str;
|
|
description = "Set the default-shell tmux variable.";
|
|
};
|
|
|
|
secureSocket = mkOption {
|
|
default = pkgs.stdenv.isLinux;
|
|
type = types.bool;
|
|
description = ''
|
|
Store tmux socket under {file}`/run`, which is more
|
|
secure than {file}`/tmp`, but as a downside it doesn't
|
|
survive user logout.
|
|
'';
|
|
};
|
|
|
|
tmuxp.enable = mkEnableOption "tmuxp";
|
|
|
|
tmuxinator.enable = mkEnableOption "tmuxinator";
|
|
|
|
plugins = mkOption {
|
|
type = with types;
|
|
listOf (either package pluginModule) // {
|
|
description = "list of plugin packages or submodules";
|
|
};
|
|
description = ''
|
|
List of tmux plugins to be included at the end of your tmux
|
|
configuration. The sensible plugin, however, is defaulted to
|
|
run at the top of your configuration.
|
|
'';
|
|
default = [ ];
|
|
example = literalExpression ''
|
|
with pkgs; [
|
|
tmuxPlugins.cpu
|
|
{
|
|
plugin = tmuxPlugins.resurrect;
|
|
extraConfig = "set -g @resurrect-strategy-nvim 'session'";
|
|
}
|
|
{
|
|
plugin = tmuxPlugins.continuum;
|
|
extraConfig = '''
|
|
set -g @continuum-restore 'on'
|
|
set -g @continuum-save-interval '60' # minutes
|
|
''';
|
|
}
|
|
]
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable (mkMerge ([
|
|
{
|
|
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 = mkAfter cfg.extraConfig; }
|
|
|
|
(mkIf cfg.secureSocket {
|
|
home.sessionVariables = {
|
|
TMUX_TMPDIR = ''''${XDG_RUNTIME_DIR:-"/run/user/$(id -u)"}'';
|
|
};
|
|
})
|
|
|
|
(mkIf (cfg.plugins != [ ]) configPlugins)
|
|
]));
|
|
}
|