#!/bin/sh # Quit on escape set -o emacs bind '"\e": "\C-W\c-d"' OPEN_MODE="new_pane" CACHE_FILE=~/.cache/project_list # Close tmux popup if any and quit exit_script () { tmux display-popup -C exit $1 } debug () { if [ "$VERBOSE" = true ]; then echo $1 fi } spinner() { local s="⣾⣽⣻⢿⡿⣟⣯⣷" local -i i=0 while :; do printf "%s\\r" "${s:$((i++%8)):1}" >&2 sleep .1 done } open_local () { # To avoid using pre-entered string in current buffer tmux send-keys C-c tmux send-keys "cd $PROJECT_PATH" Enter exit_script 0 } open_new_pane () { tmux has-session -t $SESSION_NAME 2>/dev/null if [ $? != 0 ]; then debug "Session $SESSION_NAME missing, creating it." tmux new-session -s $SESSION_NAME -d -n $PROJECT_NAME -c $PROJECT_PATH fi tmux has-session -t $SESSION_NAME:$PROJECT_NAME 2>/dev/null if [ $? != 0 ]; then debug "Window $PROJECT_NAME in $SESSION_NAME not found, creating it." tmux new-window -t $SESSION_NAME -n $PROJECT_NAME -d -c $PROJECT_PATH fi tmux switch-client -t $SESSION_NAME:$PROJECT_NAME exit_script 0 } update_project_list_cache() { PROJECT_LIST_UPDATE=$(find ~/* -name .git -type d -not -path "~/.*" -prune 2>/dev/null | sed 's/\/.git/\n/g' | sed "s/$(echo $HOME | sed 's/\//\\\//g')//" | cut -d'/' -f2-) echo $PROJECT_LIST_UPDATE > $CACHE_FILE } while getopts "lv" option; do debug "Reading option $option" case $option in l) OPEN_MODE="local" ;; v) VERBOSE=true ;; esac done declare -A CUSTOM_SESSIONS CUSTOM_SESSIONS[Projects]=Halia spinner & spinner_pid=$! if [ ! -f "$CACHE_FILE" ]; then debug "Start synchronous project list cache update" update_project_list_cache else debug "Start asynchronous project list cache update" update_project_list_cache & fi PROJECT_LIST=$(cat $CACHE_FILE) kill $spinner_pid SELECTED=$(echo $PROJECT_LIST | tr ' ' '\n' | fzf) debug "Selected $SELECTED" # Quit if nothing has been selected if [ ! $SELECTED ]; then exit_script 1 fi PROJECT_PATH=$(realpath ~/${SELECTED}) PROJECT_ROOT=$(echo $SELECTED | cut -d '/' -f1) PROJECT_NAME=$(echo $SELECTED | rev | cut -d '/' -f1 | rev) SESSION_NAME=$([ -z "${CUSTOM_SESSIONS[$PROJECT_ROOT]}" ] && echo "$PROJECT_ROOT" || echo "${CUSTOM_SESSIONS[$PROJECT_ROOT]}") debug "Project path is $PROJECT_PATH" debug "Opening in $OPEN_MODE" case $OPEN_MODE in "new_pane") open_new_pane ;; "local") open_local ;; esac