diff --git a/flake.lock b/flake.lock index 91552fb..8442ada 100644 --- a/flake.lock +++ b/flake.lock @@ -159,11 +159,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1775423009, - "narHash": "sha256-vPKLpjhIVWdDrfiUM8atW6YkIggCEKdSAlJPzzhkQlw=", + "lastModified": 1775710090, + "narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=", "owner": "nixos", "repo": "nixpkgs", - "rev": "68d8aa3d661f0e6bd5862291b5bb263b2a6595c9", + "rev": "4c1018dae018162ec878d42fec712642d214fdfa", "type": "github" }, "original": { @@ -190,11 +190,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1775305101, - "narHash": "sha256-/74n1oQPtKG52Yw41cbToxspxHbYz6O3vi+XEw16Qe8=", + "lastModified": 1776067740, + "narHash": "sha256-B35lpsqnSZwn1Lmz06BpwF7atPgFmUgw1l8KAV3zpVQ=", "owner": "nixos", "repo": "nixpkgs", - "rev": "36a601196c4ebf49e035270e10b2d103fe39076b", + "rev": "7e495b747b51f95ae15e74377c5ce1fe69c1765f", "type": "github" }, "original": { @@ -206,11 +206,11 @@ }, "nixpkgs-wsl-stable": { "locked": { - "lastModified": 1775305101, - "narHash": "sha256-/74n1oQPtKG52Yw41cbToxspxHbYz6O3vi+XEw16Qe8=", + "lastModified": 1776067740, + "narHash": "sha256-B35lpsqnSZwn1Lmz06BpwF7atPgFmUgw1l8KAV3zpVQ=", "owner": "nixos", "repo": "nixpkgs", - "rev": "36a601196c4ebf49e035270e10b2d103fe39076b", + "rev": "7e495b747b51f95ae15e74377c5ce1fe69c1765f", "type": "github" }, "original": { @@ -257,11 +257,11 @@ ] }, "locked": { - "lastModified": 1775365543, - "narHash": "sha256-f50qrK0WwZ9z5EdaMGWOTtALgSF7yb7XwuE7LjCuDmw=", + "lastModified": 1776119890, + "narHash": "sha256-Zm6bxLNnEOYuS/SzrAGsYuXSwk3cbkRQZY0fJnk8a5M=", "owner": "Mic92", "repo": "sops-nix", - "rev": "a4ee2de76efb759fe8d4868c33dec9937897916f", + "rev": "d4971dd58c6627bfee52a1ad4237637c0a2fb0cd", "type": "github" }, "original": { diff --git a/modules/home/tmux.nix b/modules/home/tmux.nix index c13ac43..15dc857 100644 --- a/modules/home/tmux.nix +++ b/modules/home/tmux.nix @@ -2,6 +2,76 @@ let cfg = config.dot.tmux; + + projectSelector = pkgs.writeScriptBin "projectSelector" '' + #!${pkgs.zsh}/bin/zsh + # Configuration + PRO_BASE_DIR="$HOME/pro" + PRO_BLACKLIST=("lost+found" ".git" "node_modules") + + # 1. Build the list of projects + list="misc" + if [[ -d "$PRO_BASE_DIR" ]]; then + for dir in "$PRO_BASE_DIR"/*(/N); do + name=$(basename "$dir") + # Check against blacklist + if [[ ! ''${PRO_BLACKLIST[(r)''${name}]} == ''${name} ]]; then + list+="\n$name" + fi + done + fi + + # 2. Open fzf (Multi-select: Tab to mark, Enter to confirm) + selected=$(echo -e "$list" | ${pkgs.fzf}/bin/fzf -m --header="Select projects" --reverse) + + [[ -z "$selected" ]] && exit 0 + + # 3. Process selections + # Convert newline-separated string to array + selected_array=("''${(@f)selected}") + total=''${#selected_array[@]} + i=0 + + for arg in "''${selected_array[@]}"; do + ((i++)) + target="" + s_name="" + + if [[ "$arg" == "misc" ]]; then + target="$HOME" + s_name="misc" + else + target="$PRO_BASE_DIR/$arg" + s_name=$(basename "$target" | tr '.' '_') + fi + + # Background load all but the last selection + if [[ $i -lt $total ]]; then + if [[ -f "$target/.tmuxp.yaml" || -f "$target/.tmuxp.yml" ]]; then + ${pkgs.tmuxp}/bin/tmuxp load --yes -d "$target" + else + if ! ${pkgs.tmux}/bin/tmux has-session -t "$s_name" 2>/dev/null; then + ${pkgs.tmux}/bin/tmux new-session -d -s "$s_name" -c "$target" + fi + fi + else + # Last item: Foreground switch/attach + if [[ -f "$target/.tmuxp.yaml" || -f "$target/.tmuxp.yml" ]]; then + ${pkgs.tmuxp}/bin/tmuxp load --yes "$target" + else + if ! ${pkgs.tmux}/bin/tmux has-session -t "$s_name" 2>/dev/null; then + ${pkgs.tmux}/bin/tmux new-session -d -s "$s_name" -c "$target" + fi + + if [[ -n "$TMUX" ]]; then + ${pkgs.tmux}/bin/tmux switch-client -t "$s_name" + else + ${pkgs.tmux}/bin/tmux attach-session -t "$s_name" + fi + fi + fi + done + ''; in { options.dot.tmux = { @@ -40,9 +110,9 @@ in bind C-t display-popup -E -xC -yC -w 95% -h 95% "tasksquire" ${lib.optionalString cfg.workMode '' - bind C-s display-popup -E "zsh ~/bin/tmuxp_selector.sh" - bind C-n display-popup -E -xC -yC -w 95% -h 95% -d "~/Documents/notes/Work/" "vim quick_notes.md" - bind C-p display-popup -E -xC -yC -w 95% -h 95% -d "~/Documents/notes/Work/development/" "vim mbpr.md" + bind C-s display-popup -E "projectSelector" + bind C-n display-popup -E -xC -yC -w 95% -h 95% -d "/mnt/c/Users/marti/Documents/notes/Work/" "vim quick_notes.md" + bind C-p display-popup -E -xC -yC -w 95% -h 95% -d "/mnt/c/Users/marti/Documents/notes/Work/development/" "vim mbpr.md" ''} ####################################### @@ -78,6 +148,95 @@ in ''; }; + programs.zsh.initExtra = lib.optionalString cfg.workMode '' + # --- 1. Configuration --- + export PRO_BASE_DIR="$HOME/pro" + export PRO_BLACKLIST=("lost+found") + + # --- 2. The 'pro' function --- + pro() { + local total_args=$# + local i=0 + + for arg in "$@"; do + ((i++)) + local target="" + local s_name="" + + # Resolve the target directory and session name + if [[ "$arg" == "misc" ]]; then + target="$HOME" + s_name="misc" + elif [[ -d "$PRO_BASE_DIR/$arg" ]]; then + target="$PRO_BASE_DIR/$arg" + s_name=$(basename "$target" | tr '.' '_') + elif [[ -d "$HOME/$arg" ]]; then + target="$HOME/$arg" + s_name=$(basename "$target" | tr '.' '_') + else + echo "Error: Project '$arg' not found in $PRO_BASE_DIR or $HOME" + continue + fi + + target=$(realpath "$target") + + # logic: If this is NOT the last argument, load it in the background. + # If it IS the last argument, load/attach to it in the foreground. + if [[ "$i" -lt "$total_args" ]]; then + # BACKGROUND LOADING + if [[ -f "$target/.tmuxp.yaml" || -f "$target/.tmuxp.yml" ]]; then + tmuxp load --yes -d "$target" + else + if ! tmux has-session -t "$s_name" 2>/dev/null; then + tmux new-session -d -s "$s_name" -c "$target" + fi + fi + else + # FOREGROUND ATTACHING (The "Winner") + if [[ -f "$target/.tmuxp.yaml" || -f "$target/.tmuxp.yml" ]]; then + # tmuxp load handles switching/attaching automatically + tmuxp load --yes "$target" + else + if ! tmux has-session -t "$s_name" 2>/dev/null; then + tmux new-session -d -s "$s_name" -c "$target" + fi + + if [[ -n "$TMUX" ]]; then + tmux switch-client -t "$s_name" + else + tmux attach-session -t "$s_name" + fi + fi + fi + done + } + + # --- 3. Tab Completion --- + _pro_completion() { + local -a projects + + # Manually add the 'misc' alias to completion + projects+=("misc") + + # Add directories from ~/pro/ + if [[ -d "$PRO_BASE_DIR" ]]; then + for dir in "$PRO_BASE_DIR"/*(/N); do + local name=$(basename "$dir") + # Nix escape for array check: if name not in blacklist + if [[ ! ''${PRO_BLACKLIST[(r)''${name}]} == ''${name} ]]; then + projects+=("''${name}") + fi + done + fi + + _describe 'projects' projects + } + + compdef _pro_completion pro + ''; + + home.packages = lib.optional cfg.workMode projectSelector; + home.shellAliases = { "o" = "tmuxp"; "ol" = "tmuxp load";