Last active
August 29, 2015 13:56
-
-
Save panta82/9261325 to your computer and use it in GitHub Desktop.
[Bash] Go To Project alias function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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