Skip to content

Instantly share code, notes, and snippets.

@panta82
Last active August 29, 2015 13:56
Show Gist options
  • Save panta82/9261325 to your computer and use it in GitHub Desktop.
Save panta82/9261325 to your computer and use it in GitHub Desktop.
[Bash] Go To Project alias function
# Alias command to quickly jump to any project on your machine.
# Advantage is given to recently altered projects and directories that hold .git repositories.
#
# Examples:
# gd # cd ~/dev/[most recently active project]
# gd project1 # cd ~/dev/c/project1
# gd pr1 # cd ~/dev/c/project1 (fuzzy search)
# gd node # cd ~/dev/node/[most recently active node project]
# gd gdfgd # nothing (no candidate found)
#
# Installation:
# - Paste this into your ~/.bashrc
# - Set GO_TO_PROJECT_ROOT to the folder where you hold your projects (eg ~/dev/)
# - Set GO_TO_PROJECT_DEPTH to the depth of the directory structure where you keep projects (eg job/c++/bigproject -> 3)
# - On the last line, set the name of the alias you want to use (by default 'gd' because I use ~/dev/, so 'go dev' :shrugs:)
# - Restart terminals or source ~/.bashrc
GO_TO_PROJECT_ROOT="${HOME}/dev"
GO_TO_PROJECT_DEPTH=3
_GO_TO_PROJECT_FILE_NAME_CUTOFF_LENGTH=`expr ${#GO_TO_PROJECT_ROOT} + 1`
go_to_project() {
local query="${1,,}"
local quality_A="$query"
local quality_B="[\\b/_-.]$query[\\b/_-.]"
local quality_C="[\\b/]$query[\\b/]"
local quality_D="^$query$"
local res_quality=0
local fuzzy_match=
for (( i=0; i<${#query}; i++ )); do
fuzzy_match="${fuzzy_match}([^/]*)${query:$i:1}"
done
#echo $fuzzy_match #debugging
export go_to_project_res_dir="."
while read dir; do
# For empty query, just go to the most recent project
if [ -z "$query" ]; then
export go_to_project_res_dir="$dir"
break
fi
local file_name="${dir:$_GO_TO_PROJECT_FILE_NAME_CUTOFF_LENGTH}"
file_name=${file_name,,}
local quality=0
[[ $file_name =~ $quality_A ]] && quality=100
[[ $file_name =~ $quality_B ]] && quality=103
[[ $file_name =~ $quality_C ]] && quality=107
[[ $file_name =~ $quality_D ]] && quality=110
# Fuzzy search if no direct match was found
if [ $quality -le 0 ] && [[ $file_name =~ $fuzzy_match ]]; then
quality=$(expr 100 - `echo ${BASH_REMATCH[@]:1} | wc -m`)
#echo "$file_name -> ${BASH_REMATCH[@]:1} -> $quality" #debugging
fi
# Give a little boost to git repositories
if [ -d "$dir/.git" ] && [ $quality -gt 0 ]; then
quality=$(expr $quality + 5)
fi
# If better quality than existing, replace
#echo "$dir -> $file_name -> $quality" #debugging
if [ $quality -gt $res_quality ]; then
res_quality="$quality"
export go_to_project_res_dir="$dir"
fi
done < <(find $GO_TO_PROJECT_ROOT -maxdepth $GO_TO_PROJECT_DEPTH \
-type d -exec ls -dt '{}' + 2>/dev/null \
| awk '{print length, $0}' | sort -n | cut -d " " -f2-)
#echo "$go_to_project_res_dir" #debugging
cd "$go_to_project_res_dir"
}
alias gd=go_to_project
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment