I don’t use your TagFiler script (I’m not that organized), but I was looking at your bash_scripts/cdt.bash and came up with the following that seems like it would eliminate the bash part of that setup.
This is written and mildly with fish 3.0.2, and there are changes coming in 3.1 which will make subprocess capture better overall, but since I don’t use TagFiler, I’m not the best tester of this. It was an interesting exercise, though:
function cdt::usage
echo "Usage: cdt TERM+
Changes directory based on tagged folders. If the first search term begins
with a `+`, a =Context folder is located."
end
function cdt::fuzzy
string replace -r -- '^\+' '' $argv |
string replace -ar -- '[:.]' '' |
string replace -ar -- '([[:alpha:]])' '$1*'
end
function cdt::mdfind -a term
argparse -x t,c -N 1 'c/context' 't/tag' 'r/root=' -- $argv
set -l folder "kMDItemContentType = 'public.folder'"
set -l root ~
set -q _flag_root
and set root $_flag_root
set -l term (cdt::fuzzy $term)
if set -q _flag_context
set term "=$term"
else
set term "@$term"
end
set -l tags "kMDItemUserTags = '$term'c"
mdfind -0 -onlyin (string escape $root) "$tags and $folder"
end
function cdt::find -a root term
find $root -maxdepth 3 -type d -iname (cdt::fuzzy $term) -print0
end
function cdt::shortest
set -l list (cat - | string split0)
set -l shortest $list[1]
set -l sl (string length $shortest)
if test (count $list) -gt 1
for found in $list[2..-1]
set -l fl (string length $fl)
if test $fl -lt $sl
set shortest $found
set sl $fl
end
end
end
test -z $shortest
and return 1
echo $shortest
return 0
end
function cdt -d 'cd to context-tagged folders'
argparse -N 1 'h/help' -- $argv
set -q _flag_help
and begin
cdt::usage 1>&2
return 0
end
# Normalize terms, which may either be separate words or joined by colons, or
# a mix of the two.
set -l terms (string replace -a -- ' ' : $argv | string split :)
set -l root ~
# If the first term starts with a `+`, it’s a context search.
if string match -qr -- '^\+' $terms[1]
set root (cdt::mdfind -c $terms[1] | string split0)[1]
set -e terms[1]
end
for term in $terms
set -l sub ''
# If the term starts with a dot, treat it as a directory name only search
if string match -qr -- '^\.'
set sub (cdt::find $root $term | cdt::shortest)
else
set sub (cdt::mdfind -r $root -t $term)
end
test -z $sub
and set sub (cdt::find $root $term | cdt::shortest)
test -d $sub
set root $sub
end
if test -d $root -a $root != ~
cd $root
return 0
else
echo 1>&2 'No target directory found.'
return 1
end
end
Thanks, I'll test this out. It was one of those scripts that was working fine running as a bash script, and I don't use it frequently, so it wasn't at the top of my list for porting. But this saves me some time :)
I don’t use your TagFiler script (I’m not that organized), but I was looking at your
bash_scripts/cdt.bash
and came up with the following that seems like it would eliminate thebash
part of that setup.This is written and mildly with fish 3.0.2, and there are changes coming in 3.1 which will make subprocess capture better overall, but since I don’t use TagFiler, I’m not the best tester of this. It was an interesting exercise, though: