Fast, fuzzy directory navigation for Tag Filer
This script provides an easy way to jump around the filesystem if (and only if) you’re using my Tag Filer system. In that system, you tag main “context” folders with “=Tagname,” and target subfolders (project folders) with “@projecttag.” The Tag Filing system allows me to tag individual files and folders with a “#Tagname” (target context) and “:project:chain” tags to have Hazel automatically move them to their destination and maintain both a shallow folder system and a tag-based search system. Get more info here.
If you have such a setup, you can source the function below in your profile and have a cdt
command available. Then, typing cdt work projectx
will jump to the folder tagged “@projectx” inside of the context folder tagged “=Work.” The command requires a context as the first argument, and any subsequent tags are project folders, but it’s forgiving about capitalization and partial tags.
In fact, it’s even fuzzy, so you could type cdt wrk projx
. You can also reach subfolders in sequence, which is handy because after the project folder I often have subfolders (e.g. asset folders) with the same name as other projects’ folders. In this scenario, cdt wrk projx img
will jump me to ~/Dropbox/Work/project-x/images/
instantly.
# In my tag-filing system where top-level "context" folders are tagged with
# "=Context" tags and subfolders are tagged with "@project" tags, this function
# lets me quickly cd to any tagged folder in my filing system. The first
# argument is a context folder, the rest are a chain of subfolders. The
# subfolders don't need to be contiguous, and the matching is fuzzy.
cdt() {
local fuzzy
local root
local sub
local list
if [[ $# == 0 || $1 =~ ^\-?\-h(elp)?$ ]]; then
cat <<-EOS
$FUNCNAME changes directory based on tagged folders
usage: $FUNCNAME context [subfolder, [subfolder...]]
EOS
return
fi
fuzzy=`echo ${1##[#=]} | sed 's/\([[:alpha:]]\)/\1*/g'`
root=`mdfind "kMDItemUserTags = '=*$fuzzy'c && kMDItemContentType = 'public.folder'"|head -n 1`
if [[ $2 ]]; then
shift
while [[ $1 ]]; do
fuzzy=`echo $1 | tr -d "@: " | sed 's/\([[:alpha:]]\)/\1*/g'`
sub=`mdfind -onlyin "$root" "kMDItemUserTags = '@$fuzzy'c && kMDItemContentType = 'public.folder'"|head -n 1`
list=`ls -1F | grep -i "${fuzzy//\*/.*}.*\/$" | head -n 1`
if [[ -n $sub ]]; then
root=$sub
elif [[ -d $root/$list ]]; then
root=$list
fi
shift
done
fi
builtin cd "$root"
}