Created
October 7, 2014 18:23
-
-
Save maxlawton/bcba030dad6f85facbcd to your computer and use it in GitHub Desktop.
Change Directory To...
This file contains 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
#!/usr/bin/env bash | |
# ========================================================================== | |
# | |
# Change Directory To... | |
# | |
# INSTALLATION | |
# | |
# Source this file in your Bash configuration (e.g. .profile, .bashrc) | |
# | |
# COMMANDS | |
# | |
# cdto, cdup | |
# Change to named directory at arbitrary depth | |
# | |
# cdp | |
# Change directory to parent, at optionally specified level | |
# | |
# USAGE | |
# | |
# cdto <dirname> | |
# Changes to a directory matching <dirname> that is a | |
# descendent of the current working directory. If the name is | |
# ambiguous, `cdto` will prompt for a resolution. | |
# | |
# cdup <dirname> | |
# Looks upwards to ancestor directories for one matching | |
# <dirname> and prompts for resolution of ambiguity. | |
# | |
# cdp [<N>] | |
# Does 'cd ../' N times (default: 1) | |
# | |
# ========================================================================== | |
function cdto() | |
{ | |
_cd_to "$@" | |
} | |
function cdup() | |
{ | |
_cd_up "$@" | |
} | |
function cdp() | |
{ | |
local p= i=${1:-1}; | |
while (( i-- )); | |
do p+=../; | |
done; | |
cd "$p$2" && pwd; | |
} | |
# -------------------------------------------------------------------------- | |
function _cd_up() | |
{ | |
local chosen=0 | |
local curdir=`pwd` | |
local curdir=${curdir#$HOME} | |
local parts=${curdir//\// } | |
if [ -n "$1" ]; then | |
chosen=$(_choose_parent "$1" ${parts[@]}) | |
fi | |
if [ "${chosen}" -lt 1 ]; then | |
_print_parent_dirs ${parts[@]} | |
echo -n "choose [1]: " | |
chosen=`_choose_a_dir` | |
((chosen++)) | |
fi | |
cdp "$chosen" | |
} | |
function _find_dirs_like() | |
{ | |
( find . -type d -name "$@" ) | |
} | |
function _print_found_dirs() | |
{ | |
local i=1; | |
for d in "$@"; do | |
printf "%4d: %s\n" $i $d | |
((i++)) | |
done | |
} | |
function _choose_a_dir() | |
{ | |
read choice | |
local choice=${choice:-1} | |
((choice--)) | |
echo -n $choice | |
} | |
function _cd_to() | |
{ | |
local found=( $(_find_dirs_like "$1") ) | |
if [ -z "$found" ]; then | |
echo "Could not find directory $1" | |
exit | |
fi | |
if [ ${#found[@]} -gt 1 ]; then | |
_print_found_dirs ${found[@]} | |
echo -n "choose [1]: " | |
local chosen=`_choose_a_dir $found` | |
local target=${found[chosen]} | |
else | |
local target="$found" | |
fi | |
echo "$target" | |
cd "$target" | |
} | |
function _print_parent_dirs() | |
{ | |
local j=$# | |
for d in "$@" | |
do | |
((j--)) | |
if [ $j -gt 0 ]; then | |
printf "%4d: %s\n" $j $d | |
fi | |
done | |
} | |
function _choose_parent() | |
{ | |
local choice="$1" | |
shift | |
local s="$#" | |
for d in "$@" | |
do | |
((s--)) | |
if [ "$d" == "$choice" ]; then | |
echo "$s" | |
return | |
elif [ "$s" -eq "0" ]; then | |
return | |
fi | |
done | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment