#!/usr/bin/env bash # This script sets things based on my current project and will set the symlink ~/Projects/current to the correct folder PROJECTS_PATH="$HOME/Projects" SYMLINC="$PROJECTS_PATH/current" function print_help(){ echo "Manages projects" echo "" echo -e "Usage: $0 []" echo "" echo -e "Commands" echo -e "list\t\t\tLists The available projects" echo -e "switch\t\t\tSwitches the current project" echo -e "\t--auto\t\tAutomatically deduce the project based on current working directory" echo -e "\t--fzf\t\tUses fzf to choose a project" echo -e "\t--dmenu\t\tUses dmenu to choose a project" echo -e "\t--rofi\t\tUses rofi to choose a project" echo -e "\t--unset\t\tUnsets the project" echo -e "\t\tSets the project" echo -e "current\t\t\tPrints the current project" echo -e "\t--notify\t\tUses notify send to print current project" echo -e "\t--path\t\tPrints the full path rather than the name" exit 0 } function list_projects(){ if [[ "$1" == "--options" ]]; then if [ -L "$SYMLINC" ]; then echo "--unset" fi echo "--new" fi find "$PROJECTS_PATH/" -maxdepth 1 -mindepth 1 -type d | xargs -L 1 basename } function switch(){ local switchto="$1" if [[ "$1" == "--auto" ]]; then if echo "$PWD" | grep -q "$PROJECTS_PATH"; then switchto=$( echo "$PWD" | sed "s#$PROJECTS_PATH/##") switchto="${switchto%/*}" if [[ "$PWD" == "$PROJECTS_PATH" ]]; then switchto="--unset" fi else switchto="--unset" fi elif [[ "$1" == "--fzf" ]]; then switchto=$(list_projects --options | fzf) elif [[ "$1" == "--dmenu" ]]; then switchto=$(list_projects --options | dmenu -i ) elif [[ "$1" == "--rofi" ]]; then switchto=$(list_projects --options | rofi -dmenu -i ) elif [[ "$1" == "--unset" ]]; then if [ -L "$SYMLINC" ]; then rm "$SYMLINC" 2> /dev/null # See note about SIGWINCH below pkill -u $USER -SIGWINCH zsh fi exit 0 fi # If $switchto is --unset, it has just been selected from one of the menus # Re-run switch with the --unset flag if [[ "$switchto" == "--unset" ]]; then switch --unset exit 0 fi if [[ "$switchto" == "--new" ]]; then new_project "$1" exit 0 fi switchto="$PROJECTS_PATH/$switchto" # This sends the SIGWINCH signal to all zsh processes # This tells zsh that the window has been resized. # Althouph we are not resizing the window, it causes zsh to re-draw the prompt pkill -u $USER -SIGWINCH zsh if [ -d "$switchto" ]; then if [ -L "$SYMLINC" ]; then rm "$SYMLINC" 2> /dev/null fi ln -s "$switchto" "$SYMLINC" else echo "No such directory $switchto" exit 1 fi } function get_current(){ if [ -L "$SYMLINC" ]; then local current=$(readlink "$SYMLINC") if [[ "$1" != "--path" ]]; then if [ -f "$current"/index.yaml ]; then current=$(cat "$current/index.yaml" | yq -r '.name') else current=$(echo "$current" | xargs -L 1 basename) fi fi if [[ "$1" == "--notify" ]]; then notify-send "Current Project" "$current" else echo "$current" fi else if [[ "$1" == "--notify" ]]; then notify-send "Current Project" "not set" else echo "" fi fi } function new_project(){ local name="$1" local default_dirs=( bin screenshots Downloads ) if [ ! -n "$name" ]; then echo -n "Project name: " read name < /dev/tty elif [[ "$name" == "--rofi" ]]; then name=$(rofi -dmenu -l 0 -p "Project name" ) elif [[ "$name" == "--dmenu" ]]; then name=$(echo "" | dmenu -l 0 -p "Project name: " ) fi # If name still empty, exit if [ ! -n "$name" ]; then exit 1 fi mkdir "$PROJECTS_PATH/$name" # Make all the directories for dir in "${default_dirs[@]}"; do mkdir "$PROJECTS_PATH/$name/$dir" done switch "$name" } function copyto(){ local current="$(get_current --path)" if [ -n "$current" ]; then local destination="$current/" if [[ "$1" == "--bin" ]]; then destination="$current/bin/" shift fi mkdir -p "$destination" cp -r "$@" "$destination" fi } if [ -n "$1" ] ; then case "$1" in -h|--help) print_help exit 0 ;; list) list_projects exit 0 ;; switch) switch "$2" exit 0 ;; current) get_current "$2" exit 0 ;; new) new_project "$2" exit 0 ;; copy) shift copyto "$@" exit 0 ;; *) echo "Unknown command $1" print_help exit 1 ;; esac fi