1
0
Fork 0

Add fstag(), a tool to tag arbitrary files using extended attributes

This commit is contained in:
tastytea 2022-04-10 08:54:29 +02:00
parent dd28a51c27
commit a3754ffe3b
Signed by: tastytea
SSH Key Fingerprint: SHA256:FBkvrOlhq5use1XEttyUGT4bUTDVA1ar9SgIc9P03cM
2 changed files with 77 additions and 0 deletions

View File

@ -0,0 +1,21 @@
#compdef fstag
local line state
_arguments '1: :->cmds' '2:file:_files' '*: :->tags' '-h[short help text]'
case ${state} in
cmds)
_values 'command' 'list[list tags]' 'add[add tags]' 'del[delete tags]' 'find[find files with tags]'
;;
tags)
if [[ ${line[1]} == "del" ]]; then
local tags=$(fstag list ${line[2]})
[[ -n ${tags} ]] && _values 'tags' ${(@s/ /)tags}
fi
;;
esac
# Local Variables:
# mode: shell-script
# End:

56
.config/zsh/functions/fstag Executable file
View File

@ -0,0 +1,56 @@
#!/usr/bin/env zsh
# tag files using extended attributes
setopt LOCAL_OPTIONS ERR_RETURN NO_UNSET PIPE_FAIL
zmodload zsh/zutil
local -a o_help=()
zparseopts -D -K -- h=o_help
if [[ ${#o_help} -ne 0 || ! -v 2 ]] || [[ ${1} != "list" && ! -v 3 ]]; then
ret=$(( ${#o_help} ^ 1 ))
print -u $(( 1 + ${ret} )) "usage: ${0} [-h] list|add|del|find <FILE|DIR> [TAG] …"
return ${ret}
fi
local cmd=${1}
shift
local file=${1}
shift
[[ -v 1 ]] && local -a tags=(${@})
zmodload zsh/attr
local namespace="user.fstag"
local _taglist=$(zgetattr ${file} ${namespace}.tags 2> /dev/null)
local -a taglist=(${(@s/,/)_taglist})
unset _taglist
case ${cmd} in
list)
[[ -n ${taglist} ]] && print ${(j/,/)taglist}
;;
add)
taglist+=(${tags})
taglist=(${(u)taglist})
zsetattr ${file} ${namespace}.tags ${(j/,/)taglist}
;;
del)
for tag in ${(@)tags}; do
taglist=(${(@)taglist:#${tag}})
done
zsetattr ${file} ${namespace}.tags "${(j/,/)taglist}"
;;
find)
for current_file in ${file}/**; do
# zgetattr ${current_file} user.fstag.tags
local _taglist=$(${0} list ${current_file})
local -a current_tags=(${(@s/,/)_taglist})
unset _taglist
local match=yes
for tag in ${(@)tags}; do
(( ${current_tags[(I)${tag}]} )) || match=no
done
if [[ ${match} == yes ]]; then
print ${current_file}: ${(j/,/)current_tags}
fi
done
;;
esac