A pure Bash implementation for a persistent directory history menu:
#
# ~/.bash_profile
#
cdHistoryFile=~/.bash_cdhistory
cd() {
builtin cd $@ && echo $PWD >> $cdHistoryFile
}
cdh() {
local IFS=$'\n'
local directories=()
for line in `tac $cdHistoryFile`; do directories+=($line); done
cnt=${#directories[@]}
for ((i = 0; i < cnt - 1; i++)) {
for ((j = i + 1; j < cnt; j++)) {
[ "${directories[$i]}" == "${directories[$j]}" ] && unset directories[$j]
}
}
directories=("${directories[@]:1:${1:-15}}")
local select=0 subset=("${directories[@]}")
until [ $select -eq 1 ]; do
select dir in ${subset[@]}; do
case $REPLY in
q) select=1; break ;;
\.) subset=("${directories[@]}"); break ;;
.*) subset=($(printf '%s\n' "${subset[@]}" | egrep "${REPLY:1}")); break ;;
*) cd $dir; select=1; break
esac
done
done
}
Explanation:
cd()
wraps the cd
shell builtin with a function that writes directory changes to a file. cdh()
displays a selection menu of the last n-number of unique directories (in descending order from most recently accessed).
Usage:
cdhistory: cdh [n]
Options:
n Get the latest number of unique directories [default: 15]
Selections:
q Quit
. Display the original list
.<regex> Filter the current list
# Change directory
Example:
[jdoe@localhost /] $ . ~/.bash_profile && cdh
1) /home/jdoe/tmp/2/3/1
2) /home/jdoe/tmp/3
3) /home/jdoe/code/projects
4) /home/jdoe/tmp/2
5) /home/jdoe/code/projects/cloud/pipeline
6) /home/jdoe/tmp/1
7) /
8) /etc
9) /usr/etc
10) /usr/share/libtool
11) /home/jdoe/tmp
#? .tmp
1) /home/jdoe/tmp/2/3/1 3) /home/jdoe/tmp/2 5) /home/jdoe/tmp
2) /home/jdoe/tmp/3 4) /home/jdoe/tmp/1
#? .3
1) /home/jdoe/tmp/2/3/1
2) /home/jdoe/tmp/3
#? 2
[jdoe@localhost /home/jdoe/tmp/3] $