#!/usr/bin/env bash # Ensure Homebrew and standard paths are accessible inside fzf's preview subshell export PATH="/opt/homebrew/bin:/usr/local/bin:$HOME/.local/bin:$PATH" # Tabs definition TABS=("All" "Projects" "Dotfiles" "Blank Session") TOTAL=${#TABS[@]} ACTIVE_TAB=0 # Terminal Palette Colors for the Tab Header (Ghostty palette 12 and 8) CLR_ACTIVE=$(printf '\033[1;38;5;12m') CLR_INACTIVE=$(printf '\033[38;5;8m') CLR_RESET=$(printf '\033[0m') # Dynamic Previewer (Restored exact working structure from your original script) preview_cmd=' if [ "{}" = "[Create Blank Session in ~]" ]; then echo "Will spawn an empty session in ~/" elif [ -d {} ]; then if command -v eza >/dev/null 2>&1; then eza --tree --level=2 --icons --color=always --git-ignore -I "node_modules|build|dist|target|.cache" {} elif command -v tree >/dev/null 2>&1; then tree -C -L 2 --gitignore -I "node_modules|build|dist|target|.cache" {} else ls -la --color=always {} fi else tmux list-windows -t {} 2>/dev/null || echo "Session or path: {}" fi' get_projects() { if command -v fd &>/dev/null; then [ -d "$HOME/Projects" ] && fd --type d --max-depth 2 . "$HOME/Projects" 2>/dev/null | sed 's:/*$::' [ -d "$HOME/personal/Projects" ] && fd --type d --min-depth 2 --max-depth 2 . "$HOME/personal/Projects" 2>/dev/null | sed 's:/*$::' else if [ -d "$HOME/Projects" ]; then find "$HOME/Projects" -mindepth 1 -maxdepth 2 \ \( -name ".git" -o -name "node_modules" -o -name "build" -o -name ".cache" \) -prune \ -o -type d -print 2>/dev/null | sed 's:/*$::' fi if [ -d "$HOME/personal/Projects" ]; then find "$HOME/personal/Projects" -mindepth 2 -maxdepth 2 \ \( -name ".git" -o -name "node_modules" -o -name "build" -o -name ".cache" \) -prune \ -o -type d -print 2>/dev/null | sed 's:/*$::' fi fi } get_dotfiles() { if command -v fd &>/dev/null; then # 1. Standard ~/.config/ [ -d "$HOME/.config" ] && fd --type d --max-depth 1 . "$HOME/.config" 2>/dev/null | sed 's:/*$::' # 2. ~/dotfiles direct packages (e.g. ~/dotfiles/nvim, ~/dotfiles/tmux) # and stow structures (e.g. ~/dotfiles/nvim/.config/nvim or ~/dotfiles/.config/*) if [ -d "$HOME/dotfiles" ]; then # Top-level dotfile modules (depth 1) fd --type d --max-depth 1 . "$HOME/dotfiles" 2>/dev/null | sed 's:/*$::' # Unhide and drill down specifically into any .config folders inside dotfiles fd --type d --hidden --no-ignore --max-depth 4 \ --full-path '.*/\.config/[^/]+$' "$HOME/dotfiles" 2>/dev/null | sed 's:/*$::' fi else # Fallback using find if [ -d "$HOME/.config" ]; then find "$HOME/.config" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed 's:/*$::' fi if [ -d "$HOME/dotfiles" ]; then # Dotfiles packages + nested .config targets up to 4 levels deep find "$HOME/dotfiles" -mindepth 1 -maxdepth 4 \ \( -name ".git" -o -name "node_modules" -o -name ".cache" \) -prune \ -o -type d -print 2>/dev/null | grep -E '(dotfiles/[^/]+$|/\.config/[^/]+$)' | sed 's:/*$::' fi fi | sort -u } get_items_for_tab() { local tab_idx=$1 case "$tab_idx" in 1) # Projects only get_projects ;; 2) # Dotfiles only get_dotfiles ;; 3) # Blank Session echo "[Create Blank Session in ~]" ;; *) # All: tmux sessions + projects + dotfiles + top-level home dirs tmux list-sessions -F "#S" 2>/dev/null get_projects get_dotfiles find "$HOME" -maxdepth 1 -mindepth 1 -type d ! -name "Library" 2>/dev/null | sed 's:/*$::' ;; esac } render_header() { local active=$1 local out="" for i in "${!TABS[@]}"; do local name="${TABS[$i]}" if [ "$i" -eq "$active" ]; then out+="${CLR_ACTIVE}[▶ ${name}]${CLR_RESET} " else out+="${CLR_INACTIVE} ${name} ${CLR_RESET} " fi done printf "%s\n" "$out" } # --------------------------------------------------------- # Tab Navigation Loop # --------------------------------------------------------- selected="" while true; do fzf_output=$( { render_header "$ACTIVE_TAB"; get_items_for_tab "$ACTIVE_TAB" | grep -v '^$'; } | fzf \ --ansi \ --header-lines=1 \ --expect=tab,btab \ --layout=reverse \ --border=rounded \ --margin=15 \ --padding=0 \ --height=100% \ --prompt="󱇗 " \ --color="bg:#090E13,bg+:#22262D,fg:#c5c9c7,fg+:#ffffff" \ --color="hl:#7fb4ca,hl+:#7fb4ca,prompt:#7fb4ca,pointer:#22262D" \ --color="info:#5C6066,spinner:#5C6066,header:#5C6066,border:#2d3139" \ --color="label:#7fb4ca" \ --preview="$preview_cmd" \ --preview-window="right:55%:border-left") fzf_status=$? # Cancelled via Escape or Ctrl-C [[ $fzf_status -ne 0 && $fzf_status -ne 1 ]] && exit 0 key=$(echo "$fzf_output" | head -n 1) selection=$(echo "$fzf_output" | tail -n +2) if [ "$key" = "tab" ]; then ACTIVE_TAB=$(( (ACTIVE_TAB + 1) % TOTAL )) elif [ "$key" = "btab" ]; then ACTIVE_TAB=$(( (ACTIVE_TAB - 1 + TOTAL) % TOTAL )) else selected="$selection" break fi done [[ -z "$selected" ]] && exit 0 # Strip trailing slash if present selected="${selected%/}" # --------------------------------------------------------- # Handle Session Creation / Switching # --------------------------------------------------------- if [[ "$selected" == "[Create Blank Session in ~]" ]]; then idx=1 while tmux has-session -t "=blank-$idx" 2>/dev/null; do ((idx++)) done session_name="blank-$idx" tmux new-session -d -s "$session_name" -c "$HOME" elif [[ -d "$selected" ]]; then session_name=$(basename "$selected" | tr '.: ' '_') if ! tmux has-session -t "=$session_name" 2>/dev/null; then tmux new-session -d -s "$session_name" -c "$selected" fi else session_name="$selected" fi if [[ -z "$TMUX" ]]; then exec tmux attach-session -t "$session_name" else tmux switch-client -t "$session_name" fi