Skip to content

Instantly share code, notes, and snippets.

@maxlawton
Created October 7, 2014 18:23
Show Gist options
  • Save maxlawton/bcba030dad6f85facbcd to your computer and use it in GitHub Desktop.
Save maxlawton/bcba030dad6f85facbcd to your computer and use it in GitHub Desktop.
Change Directory To...
#!/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