diff --git a/completion/available/projects.completion.bash b/completion/available/projects.completion.bash index a46864b7..71d740cd 100644 --- a/completion/available/projects.completion.bash +++ b/completion/available/projects.completion.bash @@ -1,38 +1,39 @@ _pj() { - [ -z "$PROJECT_PATHS" ] && return - shift - [ "$1" == "open" ] && shift + [ -z "$PROJECT_PATHS" ] && return + shift + [ "$1" == "open" ] && shift - local cur prev words cword - _init_completion || return + local cur prev words cword + _init_completion || return - local IFS=$'\n' i j k + local IFS=$'\n' i j k - compopt -o filenames + compopt -o filenames - local -r mark_dirs=$(_rl_enabled mark-directories && echo y) - local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y) + local -r mark_dirs=$(_rl_enabled mark-directories && echo y) + local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y) - for i in ${PROJECT_PATHS//:/$'\n'}; do - # create an array of matched subdirs - k="${#COMPREPLY[@]}" - for j in $( compgen -d $i/$cur ); do - if [[ ( $mark_symdirs && -h $j || $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then - j+="/" - fi - COMPREPLY[k++]=${j#$i/} - done + for i in ${PROJECT_PATHS//:/$'\n'}; do + # create an array of matched subdirs + k="${#COMPREPLY[@]}" + for j in $( compgen -d $i/$cur ); do + if [[ ( $mark_symdirs && -h $j || $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then + j+="/" + fi + COMPREPLY[k++]=${j#$i/} done + done - if [[ ${#COMPREPLY[@]} -eq 1 ]]; then - i=${COMPREPLY[0]} - if [[ "$i" == "$cur" && $i != "*/" ]]; then - COMPREPLY[0]="${i}/" - fi + if [[ ${#COMPREPLY[@]} -eq 1 ]]; then + i=${COMPREPLY[0]} + if [[ "$i" == "$cur" && $i != "*/" ]]; then + COMPREPLY[0]="${i}/" fi + fi - return 0 + return 0 } complete -F _pj -o nospace pj +complete -F _pj -o nospace pjo diff --git a/plugins/available/projects.plugin.bash b/plugins/available/projects.plugin.bash index 6e4926ca..e4dc39e2 100644 --- a/plugins/available/projects.plugin.bash +++ b/plugins/available/projects.plugin.bash @@ -2,30 +2,74 @@ cite about-plugin about-plugin 'add "export PROJECT_PATHS=~/projects:~/intertrode/projects" to navigate quickly to your project directories with `pj` and `pjo`' function pj { - about 'navigate quickly to your various project directories' - group 'projects' +about 'navigate quickly to your various project directories' +group 'projects' - if [ -n "$PROJECT_PATHS" ]; then - local cmd - if [ "$1" == "open" ]; then - shift - cmd="$EDITOR" - fi +if [ -z "$PROJECT_PATHS" ]; then + echo "error: PROJECT_PATHS not set" + return 1 +fi - cmd="${cmd:-cd}" - if [ -n "$1" ]; then - for i in ${PROJECT_PATHS//:/$'\n'}; do - if [ -d "$i"/"$1" ]; then - $cmd "$i"/"$1" - return - fi - done - fi - fi +local cmd +local dest +local -a dests - echo "No such project '$1'" + +if [ "$1" == "open" ]; then + shift + cmd="$EDITOR" +fi +cmd="${cmd:-cd}" + + +if [ -z "$1" ]; then + echo "error: no project provided" + return 1 +fi + + +# collect possible destinations to account for directories +# with the same name in project directories +for i in ${PROJECT_PATHS//:/$'\n'}; do + if [ -d "$i"/"$1" ]; then + dests+=("$i/$1") + fi +done + + +# when multiple destinations are found, present a menu +if [ ${#dests[@]} -eq 0 ]; then + echo "error: no such project '$1'" + return 1 + +elif [ ${#dests[@]} -eq 1 ]; then + dest="${dests[0]}" + +elif [ ${#dests[@]} -gt 1 ]; then + PS3="Multiple project directories found. Please select one: " + dests+=("cancel") + select d in "${dests[@]}"; do + case $d in + "cancel") + return + ;; + *) + dest=$d + break + ;; + esac + done + +else + echo "error: please report this error" + return 1 # should never reach this + +fi + + +$cmd "$dest" } alias pjo="pj open"