dotfiles/.config/hypr/scripts/RofiThemeSelector.sh
2025-12-15 18:20:18 +01:00

154 lines
5.5 KiB
Bash
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# /* ---- 💫 https://github.com/JaKooLit 💫 ---- */  #
# Rofi Themes - Script to preview and apply themes by live-reloading the config.
# --- Configuration ---
ROFI_THEMES_DIR_CONFIG="$HOME/.config/rofi/themes"
ROFI_THEMES_DIR_LOCAL="$HOME/.local/share/rofi/themes"
ROFI_CONFIG_FILE="$HOME/.config/rofi/config.rasi"
ROFI_THEME_FOR_THIS_SCRIPT="$HOME/.config/rofi/config-rofi-theme.rasi" # A separate rofi theme for the picker itself
IDIR="$HOME/.config/swaync/images" # For notifications
# --- Helper Functions ---
# Function to send a notification
notify_user() {
notify-send -u low -i "$1" "$2" "$3"
}
# Function to apply the selected rofi theme to the main config file
apply_rofi_theme_to_config() {
local theme_name_to_apply="$1"
# Find the full path of the theme file
local theme_path
if [[ -f "$ROFI_THEMES_DIR_CONFIG/$theme_name_to_apply" ]]; then
theme_path="$ROFI_THEMES_DIR_CONFIG/$theme_name_to_apply"
elif [[ -f "$ROFI_THEMES_DIR_LOCAL/$theme_name_to_apply" ]]; then
theme_path="$ROFI_THEMES_DIR_LOCAL/$theme_name_to_apply"
else
notify_user "$IDIR/error.png" "Error" "Theme file not found: $theme_name_to_apply"
return 1
fi
# Use ~ for the home directory in the config path
local theme_path_with_tilde="~${theme_path#$HOME}"
# Create a temporary file to safely edit the config
local temp_rofi_config_file
temp_rofi_config_file=$(mktemp)
cp "$ROFI_CONFIG_FILE" "$temp_rofi_config_file"
# Comment out any existing @theme entry
sed -i -E 's/^(\s*@theme)/\\/\\/\1/' "$temp_rofi_config_file"
# Add the new @theme entry at the end of the file
echo "@theme \"$theme_path_with_tilde\"" >>"$temp_rofi_config_file"
# Overwrite the original config file
cp "$temp_rofi_config_file" "$ROFI_CONFIG_FILE"
rm "$temp_rofi_config_file"
# Prune old commented-out theme lines to prevent clutter
local max_lines=10
local total_lines=$(grep -c '^//\s*@theme' "$ROFI_CONFIG_FILE")
if [ "$total_lines" -gt "$max_lines" ]; then
local excess=$((total_lines - max_lines))
for ((i = 1; i <= excess; i++)); do
sed -i '0,/^\s*\/\/@theme/s///' "$ROFI_CONFIG_FILE"
done
fi
return 0
}
# --- Main Script Execution ---
# Check for required directories and files
if [ ! -d "$ROFI_THEMES_DIR_CONFIG" ] && [ ! -d "$ROFI_THEMES_DIR_LOCAL" ]; then
notify_user "$IDIR/error.png" "E-R-R-O-R" "No Rofi themes directory found."
exit 1
fi
if [ ! -f "$ROFI_CONFIG_FILE" ]; then
notify_user "$IDIR/error.png" "E-R-R-O-R" "Rofi config file not found: $ROFI_CONFIG_FILE"
exit 1
fi
# Backup the original config content
original_rofi_config_content_backup=$(cat "$ROFI_CONFIG_FILE")
# Generate a sorted list of available theme file names
mapfile -t available_theme_names < <((
find "$ROFI_THEMES_DIR_CONFIG" -maxdepth 1 -name "*.rasi" -type f -printf "%f\n" 2>/dev/null
find "$ROFI_THEMES_DIR_LOCAL" -maxdepth 1 -name "*.rasi" -type f -printf "%f\n" 2>/dev/null
) | sort -V -u)
if [ ${#available_theme_names[@]} -eq 0 ]; then
notify_user "$IDIR/error.png" "No Rofi Themes" "No .rasi files found in theme directories."
exit 1
fi
# Find the currently active theme to set as the initial selection
current_selection_index=0
current_active_theme_path=$(grep -oP '^\s*@theme\s*"\K[^"]+' "$ROFI_CONFIG_FILE" | tail -n 1)
if [ -n "$current_active_theme_path" ]; then
current_active_theme_name=$(basename "$current_active_theme_path")
for i in "${!available_theme_names[@]}"; do
if [[ "${available_theme_names[$i]}" == "$current_active_theme_name" ]]; then
current_selection_index=$i
break
fi
done
fi
# Main preview loop
while true; do
theme_to_preview_now="${available_theme_names[$current_selection_index]}"
# Apply the theme for preview
if ! apply_rofi_theme_to_config "$theme_to_preview_now"; then
echo "$original_rofi_config_content_backup" >"$ROFI_CONFIG_FILE"
notify_user "$IDIR/error.png" "Preview Error" "Failed to apply $theme_to_preview_now. Reverted."
exit 1
fi
# Prepare theme list for Rofi
rofi_input_list=""
for theme_name_in_list in "${available_theme_names[@]}"; do
rofi_input_list+="$(basename "$theme_name_in_list" .rasi)\n"
done
rofi_input_list_trimmed="${rofi_input_list%\\n}"
# Launch Rofi and get user's choice
chosen_index_from_rofi=$(echo -e "$rofi_input_list_trimmed" |
rofi -dmenu -i \
-format 'i' \
-p "Rofi Theme" \
-mesg "‼️ **note** ‼️ Enter: Preview || Ctrl+S: Apply &amp; Exit || Esc: Cancel" \
-config "$ROFI_THEME_FOR_THIS_SCRIPT" \
-selected-row "$current_selection_index" \
-kb-custom-1 "Control+s")
rofi_exit_code=$?
# Handle Rofi's exit code
if [ $rofi_exit_code -eq 0 ]; then # Enter
if [[ "$chosen_index_from_rofi" =~ ^[0-9]+$ ]] && [ "$chosen_index_from_rofi" -lt "${#available_theme_names[@]}" ]; then
current_selection_index="$chosen_index_from_rofi"
fi
elif [ $rofi_exit_code -eq 1 ]; then # Escape
notify_user "$IDIR/note.png" "Rofi Theme" "Selection cancelled. Reverting to original theme."
echo "$original_rofi_config_content_backup" >"$ROFI_CONFIG_FILE"
break
elif [ $rofi_exit_code -eq 10 ]; then # Custom bind 1 (Ctrl+S)
notify_user "$IDIR/ja.png" "Rofi Theme Applied" "$(basename "$theme_to_preview_now" .rasi)"
break
else # Error or unexpected exit code
notify_user "$IDIR/error.png" "Rofi Error" "Unexpected Rofi exit ($rofi_exit_code). Reverting."
echo "$original_rofi_config_content_backup" >"$ROFI_CONFIG_FILE"
break
fi
done
exit 0