
It now works completely and in a much more optimized way.

INSTRUCTIONS:
1.- Launch the gen-thunar-emblems-colors-actions script (below) to generate the needed framework
2.- Copy the switch-emblem-color script (below) to the folder YOU DECLARED in the gen-thunar-emblems-colors-actions script.
3.- Test with the test-emblems script (below). Preferably copy the test script to the desktop, give it run permissions (chmod +x test-emblems) and leave only a thunar window open showing the blue, green or whatever subfolder is used in the script.
gen-thunar-emblems-colors-actions follows:
Code: Select all
#!/bin/bash
# gen-thunar-emblems-colors-actions
# 2025-03 M. Eerie --> forum.porteus.org
script_path=""
paths=("${HOME}/.local/bin" "${HOME}/bin") # Lookup for user scripts
for path in "${paths[@]}"; do
if echo "$PATH" | grep -qE "(^|:)$path(:|$)" || [ -d "$path" ]; then
script_path="${path%/}/switch-emblem-color"
break
fi
done
if [ -z "$script_path" ]; then
read -p "Enter path to your script: (e.g., /home/guest/bin/): " -i "${HOME}/bin/" user_path
! [ -d "$user_path" ] && mkdir -p "$user_path"
script_path="${user_path%/}/switch-emblem-color"
fi
# Emblems Colors
colors=("blue" "green" "magenta" "orange" "purple" "red" "skyblue" "yellow")
gencommand==$(command -v magick || command -v convert)
PS3="Give a name to your Labels folder: "
options=("Spotlight" "Colormarks" "Scattergories" "Favorites" "ColorLabels" "Other")
select labels in "${options[@]}"; do
[[ $labels == "Other" ]] && read -p "Enter the desired name for your Labels folder: " labels
if [ -n "$labels" ]; then
for color in "${colors[@]}"; do
bookmark=$HOME/$labels/$color
mkdir -p "$bookmark"
echo "file://$bookmark" >> "$HOME/.config/gtk-3.0/bookmarks"
if [ -n "$gencommand" ]; then
"$gencommand" -size 48x48 xc:none -fill "$color" -draw "circle 24,24 24,46" "$bookmark/folder.png"
else
echo "Switching emblem color: $color for bookmark: $bookmark"
switch-emblem-color "$color" "$bookmark"
fi
done
break
else
echo "Invalid option. Try again."
fi
done
echo "Thunar bookmarks created"
# Path to Thunar Sendto .desktop files
th_actions_path="$HOME/.local/share/Thunar/sendto"
mkdir -p "$th_actions_path" # Create if necessary
# Generate .desktop files for each color defined above
for color in "${colors[@]}"; do
cat <<EOL > "$th_actions_path/tag-$color.desktop"
[Desktop Entry]
Version=1.0
Name=Tag $color
Comment=Tag $color
Exec=sh -c '$script_path $color %F'
Terminal=false
Icon=emblem-color-$color
Type=Application
Path=
StartupNotify=false
EOL
done
echo "Thunar .desktop files created in $th_actions_path"
# Create emblem icons
PS3="Please select your preferred emblem: "
select choice in circles labels
do
case $choice in
circles) draw="<circle r='8' cx='8' cy='8' style='fill:\${color}' stroke='#000' stroke-width='.4'/>"
break ;;
labels) draw="<path d='m2 2.997s-1 .003-1 1.003v8s0 1 1 1h9l4-5-4-5z' style='fill:\${color}' stroke='#000' stroke-width='.4'/>"
break ;;
*) echo "Invalid option. Exiting." && break ;;
esac
done
[ -d "$HOME/.icons/hicolor/scalable/emblems" ] || mkdir -p "$HOME/.icons/hicolor/scalable/emblems"
cd "$HOME/.icons/hicolor/scalable/emblems" || exit
colors=("blue" "green" "magenta" "orange" "purple" "red" "skyblue" "yellow")
for color in "${colors[@]}"; do
cat > emblem-color-$color.svg <<EOF
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="16" height="16">
${draw//\$\{color\}/$color}
</svg>
EOF
done
echo "Emblem icons created in $HOME/.icons/hicolor/scalable/emblems"
exit 0
Code: Select all
#!/bin/bash
# switch-emblem-color
# v. 2025-03-04 by M. Eerie --> forum.porteus.org
# This Bash script is designed to manage file emblems and symbolic links based on user-specified options.
# It allows the user to:
# - Tag files with emblems: Assigns a color-based emblem to a file and creates a symbolic link in a designated directory.
# - Untag files: Removes all emblems from a file and deletes any associated symbolic links.
# - List emblems: Displays the current emblems assigned to a file.
# The script ensures that symbolic links are correctly created or removed according to the presence of the corresponding emblems,
# effectively organizing files based on their tags.
# Usage: $0 <color|untag|list> <file1> [file2 ... fileN]
option="$1"
shift # Ignore 1st argument ("option"). Now $@ becomes the files
[ -z "$option" ] && exit 1
manage_symlink() {
local action="$1" file="$2" emblem="$3"
local destination_dir="$HOME/Scattergories/$emblem"
local symlink="$destination_dir/${file##*/}"
case "$action" in
create) mkdir -p "$destination_dir" && ln -sf "$(realpath "$file")" "$symlink" ;;
delete) [ -L "$symlink" ] && [ "$(readlink "$symlink")" = "$(realpath "$file")" ] && rm "$symlink" ;;
esac
}
for file in "$@"; do
emblems=$(gio info -a metadata::emblems "$file" | sed -n 's/metadata::emblems: \[\(.*\)\]/\1/p')
case "$option" in
untag)
gio set -t unset "$file" metadata::emblems
find "$HOME/Scattergories/" -type l -samefile "$(realpath "$file")" -delete ;;
list) echo "$file: $emblems" ;;
*)
emblem="emblem-color-$option"
# Create comma-separated array from emblems list
IFS=',' read -ra arr <<< "$emblems"
for i in "${!arr[@]}"; do
arr[i]=$(echo "${arr[i]}" | xargs) # Remove spaces
done
arr=($(printf "%s\n" "${arr[@]}" | awk NF)) # Remove empty elements from array
found=0
for i in "${!arr[@]}"; do
if [ "${arr[i]}" = "$emblem" ]; then
found=1
break
fi
done
if [ "$found" -eq 0 ]; then
arr+=("$emblem")
manage_symlink create "$file" "$option"
else
arr=("${arr[@]/$emblem}")
manage_symlink delete "$file" "$option"
fi
emblems=$(IFS=','; echo "${arr[*]}") # Properly rebuild the emblems string
# Update metadata::emblems key
[ -z "$emblems" ] && gio set -t unset "$file" metadata::emblems || \
gio set -t stringv "$file" metadata::emblems "${arr[@]}"
touch -cr "$file" "$file" # Keep time mark from original file
;;
esac
done
test-emblems script:
Code: Select all
#!/bin/bash
desktop_dir=$(xdg-user-dir DESKTOP)
cd "$desktop_dir" || ( echo "Desktop directory not found." && exit )
file="kk kk"
[ -f "$file" ] && toggle-emblem-color untag "$file" || touch "$file"
colors=("blue" "green" "yellow" "red" "orange")
for i in {1..15}
do
random_color=${colors[$RANDOM % ${#colors[@]}]} # Select random color
command=" toggle-emblem-color $random_color '$file'"
eval "$command" && sleep 1
done
toggle-emblem-color untag "$file"
toggle-emblem-color list "$file"
rm "$file"
Code: Select all
#!/bin/bash
xml_file="$HOME/.config/Thunar/uca.xml"
### Create a backup first
cp "$xml_file"{,.bak}
# Color names
names=("Blue" "Green" "Magenta" "Orange" "Purple" "Red" "Skyblue" "Yellow")
write_record=""
for i in {0..7}; do
unique_id="$(date +%s%N)-$((i+1))"
record="<action>
<icon>emblem-color-${names[i],,}</icon>
<name>${names[i]}</name>
<submenu>Etiquetas</submenu>
<unique-id>${unique_id}</unique-id>
<command>sh -c "~/.local/bin/toggle-emblem-color ${names[i]} %F"</command>
<description>Poner/Quitar etiqueta ${names[i],,}</description>
<range>*</range>
<patterns>*</patterns>
<directories/>
<audio-files/>
<image-files/>
<other-files/>
<text-files/>
<video-files/>
</action>"
write_record="${write_record}${record}\n"
done
temp_file=$(mktemp)
{ head -n -1 "$xml_file"; printf "%b" "$write_record"; tail -n 1 "$xml_file"; } > "$temp_file"
mv "$temp_file" "$xml_file"
Installation Demo:

Testing Demo:

Feedback much appreciated.

EDIT:
* Removed trailing slash preventing correct operation with filenames containing spaces
Code: Select all
--- local destination_dir="$HOME/Scattergories/$emblem/"
+++ local destination_dir="$HOME/Scattergories/$emblem"
* Fixed a bug in switch-emblem-color that deleted the existing symlink when adding a next emblem. Now as many symlinks are created (and deleted) as emblems.
* Added option to create folder.png icons for each generated color folder
* Added a script to generate a Tags menu in Thunar