{ config, lib, pkgs, ... }: with lib; let inherit (pkgs) stdenv; cfg = config.programs.tmux; tmux = pkgs.runCommand pkgs.tmux.name { buildInputs = [ pkgs.makeWrapper ]; } '' source $stdenv/setup mkdir -p $out/bin makeWrapper ${pkgs.tmux}/bin/tmux $out/bin/tmux \ --set __ETC_BASHRC_SOURCED "" \ --set __ETC_ZPROFILE_SOURCED "" \ --set __ETC_ZSHENV_SOURCED "" \ --set __ETC_ZSHRC_SOURCED "" \ --set __NIX_DARWIN_SET_ENVIRONMENT_DONE "" \ --add-flags -f --add-flags /etc/tmux.conf ''; text = import ../lib/write-text.nix { inherit lib; mkTextDerivation = name: text: pkgs.writeText "tmux-options-${name}" text; }; tmuxOptions = concatMapStringsSep "\n" (attr: attr.text) (attrValues cfg.tmuxOptions); fzfTmuxSession = pkgs.writeScript "fzf-tmux-session" '' #! ${stdenv.shell} set -e session=$(tmux list-sessions -F '#{session_name}' | fzf --query="$1" --exit-0) tmux switch-client -t "$session" ''; in { imports = [ (mkRenamedOptionModule [ "programs" "tmux" "tmuxConfig" ] [ "programs" "tmux" "extraConfig" ]) (mkRemovedOptionModule [ "programs" "tmux" "defaultCommand" ] "Use `programs.tmux.extraConfig` to configure the default command instead. If unset, tmux will default to using your system configured login shell.") ]; options = { programs.tmux.enable = mkOption { type = types.bool; default = false; description = "Whether to configure tmux."; }; programs.tmux.enableSensible = mkOption { type = types.bool; default = false; example = true; description = "Enable sensible configuration options for tmux."; }; programs.tmux.enableMouse = mkOption { type = types.bool; default = false; example = true; description = "Enable mouse support for tmux."; }; programs.tmux.enableFzf = mkOption { type = types.bool; default = false; example = true; description = "Enable fzf keybindings for selecting tmux sessions and panes."; }; programs.tmux.enableVim = mkOption { type = types.bool; default = false; example = true; description = "Enable vim style keybindings for copy mode, and navigation of tmux panes."; }; programs.tmux.iTerm2 = mkOption { type = types.bool; default = false; example = true; description = "Cater to iTerm2 and its tmux integration, as appropriate."; }; programs.tmux.tmuxOptions = mkOption { internal = true; type = types.attrsOf (types.submodule text); default = {}; }; programs.tmux.extraConfig = mkOption { type = types.lines; default = ""; description = "Extra configuration to add to {file}`tmux.conf`."; }; }; config = mkIf cfg.enable { warnings = mkIf cfg.iTerm2 [ "The programs.tmux.iTerm2 is no longer needed and doesn't do anything anymore" ]; environment.systemPackages = [ # Include wrapped tmux package. tmux ]; environment.etc."tmux.conf".text = '' ${tmuxOptions} ${cfg.extraConfig} source-file -q /etc/tmux.conf.local ''; programs.tmux.tmuxOptions.sensible.text = mkIf cfg.enableSensible '' set -g default-terminal "screen-256color" setw -g aggressive-resize on set -g base-index 1 set -g renumber-windows on set -g status-keys emacs set -s escape-time 0 bind c new-window -c '#{pane_current_path}' bind % split-window -v -c '#{pane_current_path}' bind '"' split-window -h -c '#{pane_current_path}' # TODO: make these interactive bind C new-session bind S switch-client -l # set -g status-utf8 on # set -g utf8 on ''; programs.tmux.tmuxOptions.mouse.text = mkIf cfg.enableMouse '' set -g mouse on setw -g mouse on set -g terminal-overrides 'xterm*:smcup@:rmcup@' ''; programs.tmux.tmuxOptions.fzf.text = mkIf cfg.enableFzf '' bind-key -n M-p run "tmux split-window -p 40 -c '#{pane_current_path}' 'tmux send-keys -t #{pane_id} \"$(fzf -m | paste -sd\\ -)\"'" bind-key -n M-s run "tmux split-window -p 40 'tmux send-keys -t #{pane_id} \"$(${fzfTmuxSession})\"'" ''; programs.tmux.tmuxOptions.vim.text = mkIf cfg.enableVim ('' setw -g mode-keys vi bind h select-pane -L bind j select-pane -D bind k select-pane -U bind l select-pane -R bind s split-window -v -c '#{pane_current_path}' bind v split-window -h -c '#{pane_current_path}' bind-key -T copy-mode-vi p send-keys -X copy-pipe-and-cancel "tmux paste-buffer" bind-key -T copy-mode-vi v send-keys -X begin-selection '' + optionalString stdenv.isLinux '' bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel '' + optionalString stdenv.isDarwin '' bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy" ''); }; }