diff --git a/nix/configurations/vanadium/home/programs.nix b/nix/configurations/vanadium/home/programs.nix index 2836b1af..0ba0f0ac 100644 --- a/nix/configurations/vanadium/home/programs.nix +++ b/nix/configurations/vanadium/home/programs.nix @@ -23,6 +23,7 @@ pkgs.hutils pkgs.miniserve pkgs.agenix + pkgs.tmux-sessionizer # pdf pkgs.poppler_utils # pdfseparate, pdfunite diff --git a/nix/homeModules/common/fish/default.nix b/nix/homeModules/common/fish/default.nix index 3ac5f313..d5ce080e 100644 --- a/nix/homeModules/common/fish/default.nix +++ b/nix/homeModules/common/fish/default.nix @@ -23,11 +23,10 @@ in { programs.direnv.config.whitelist.prefix = [(config.home.sessionVariables.REPO_PATH + "/leana8959")]; programs.tmux.extraConfig = lib.mkBefore '' # sessionizer binds - bind -n C-f run-shell "tmux new-window ${fishExe} -c tmux-sessionizer" - bind -n C-g run-shell "${fishExe} -c tmux-home" - bind s run-shell "${fishExe} -c tmux-last" + bind -n C-f run-shell "tmux new-window tmux-sessionizer" + bind s run-shell "tmux-last" ''; - programs.kitty.settings.shell = ''${fishExe} --command="tmux-home"''; + programs.kitty.settings.shell = ''${fishExe}''; # # Script dependencies @@ -53,11 +52,21 @@ in { # # Scripts and functions # - xdg.configFile = - lib.mapAttrs' - (path: _: - lib.nameValuePair "fish/functions/${path}" {source = "${./functions}/${path}";}) - (builtins.readDir ./functions); + xdg.configFile = let + allFunctions = + lib.mapAttrs' + (path: _: + lib.nameValuePair "fish/functions/${path}" {source = "${./functions}/${path}";}) + (builtins.readDir ./functions); + in + builtins.removeAttrs allFunctions [ + "fish/functions/__tmux-attach-or-switch.fish" + "fish/functions/__tmux-maybe-create.fish" + "fish/functions/__tmux-register-session.fish" + "fish/functions/tmux-home.fish" + "fish/functions/tmux-last.fish" + "fish/functions/tmux-sessionizer.fish" + ]; programs.fish = { interactiveShellInit = builtins.readFile ./shellInit.fish; diff --git a/nix/nixosModules/extra/leana.nix b/nix/nixosModules/extra/leana.nix index 57920d83..0f884580 100644 --- a/nix/nixosModules/extra/leana.nix +++ b/nix/nixosModules/extra/leana.nix @@ -6,7 +6,6 @@ # # My user # - programs.fish.enable = true; nix.settings.trusted-users = ["leana"]; users.users."leana" = { isNormalUser = true; @@ -14,7 +13,7 @@ description = "Leana"; group = "leana"; extraGroups = ["wheel"]; - shell = pkgs.fish; + shell = pkgs.bash; openssh.authorizedKeys.keys = config.users.users.root.openssh.authorizedKeys.keys; }; users.groups.leana = {}; diff --git a/nix/packages/by-name/tmux-sessionizer/package.nix b/nix/packages/by-name/tmux-sessionizer/package.nix new file mode 100644 index 00000000..c00e3747 --- /dev/null +++ b/nix/packages/by-name/tmux-sessionizer/package.nix @@ -0,0 +1,127 @@ +{ + writeShellApplication, + tmux, + procps, + fzf, + gnused, + lib, + symlinkJoin, +}: let + tmux-register-session = writeShellApplication { + name = "__tmux-register-session"; + runtimeInputs = [tmux]; + text = '' + last=/tmp/TMUX_LAST + + # bail if tmux not running + if ! pgrep tmux >/dev/null 2>&1; then + exit 1 + fi + + this="$(tmux display-message -p '#S')" + if [ ! -f "$last" ] || [ "$(cat "$last")" != "$this" ]; then + echo "$this" >"$last" + fi + ''; + }; + + tmux-maybe-create = writeShellApplication { + name = "__tmux-maybe-create"; + runtimeInputs = [procps tmux]; + text = '' + session_name="$1" + session_dir="$2" + + if ! pgrep tmux >/dev/null 2>&1 || ! tmux has -t="$session_name" 2>/dev/null; then + tmux new-session -ds "$session_name" -c "$session_dir" + fi + ''; + }; + + tmux-attach-or-switch = writeShellApplication { + name = "__tmux-attach-or-switch"; + runtimeInputs = [tmux]; + text = '' + session_name="$1" + TMUX=''${TMUX:-} + + if [ -z "$TMUX" ]; then + tmux attach-session -t "$session_name" + else + tmux switch-client -t "$session_name" + fi + ''; + }; + + tmux-last = writeShellApplication { + name = "tmux-last"; + text = '' + tmux_last=/tmp/TMUX_LAST + if [ ! -f $tmux_last ]; then + echo "Last session is not yet set" + return 1 + fi + + session_name="$(cat $tmux_last)" + session_path="$session_name" + if [ ! -d "$session_path" ]; then + session_path="/tmp" + fi + + # bail if not in tmux, nothing to register + ${lib.getExe tmux-register-session} || : + ${lib.getExe tmux-maybe-create} "$session_name" "$session_path" + ${lib.getExe tmux-attach-or-switch} "$session_name" + ''; + }; + + tmux-sessionizer = writeShellApplication { + name = "tmux-sessionizer"; + runtimeInputs = [fzf gnused]; + text = '' + selected=$( + { + fd . "$REPO_PATH" --exact-depth 2 --hidden --type d + fd . "$WORKTREE_PATH" --exact-depth 3 --hidden --type d + fd . "$PLAYGROUND_PATH" --exact-depth 1 --hidden --type d + echo "dotfiles" + echo "password-store" + } 2> /dev/null | sed -e "s|^$HOME|~|" | fzf) + selected=''${selected//\~/$HOME} + + if [ -z "$selected" ]; then + return 0 + fi + + # derive session name based on selected path + # dots are meaningful in tmux, remove them + session_name=''${selected//./_} + + # fixup special cases, override derived session_name if necessary + # this should be id for non-special cases + case "$selected" in + dotfiles) + selected=~/.dotfiles + ;; + password-store) + selected="$PASSWORD_STORE_DIR" + ;; + esac + + # effects + ${lib.getExe tmux-register-session} || : + ${lib.getExe tmux-maybe-create} "$session_name" "$selected" + ${lib.getExe tmux-attach-or-switch} "$session_name" + ''; + }; +in + symlinkJoin { + name = "tmux-sessionizer"; + paths = [ + tmux-register-session + tmux-maybe-create + tmux-attach-or-switch + tmux-last + tmux-sessionizer + ]; + }