#!/usr/bin/env bash # # This code is released in public domain by Dave Davenport # ROFI=$(which rofi) SED=$(which sed) MKTEMP=$(which mktemp) if [ -z "${SED}" ] then echo "Did not find 'sed', script cannot continue." exit 1 fi if [ -z "${MKTEMP}" ] then echo "Did not find 'mktemp', script cannot continue." exit 1 fi if [ -z "${ROFI}" ] then echo "Did not find rofi, there is no point to continue." exit 1 fi TMP_CONFIG_FILE=$(${MKTEMP}) ## # Array with parts to the found themes. # And array with the printable name. ## declare -a themes declare -a theme_names ## # Function that tries to find all installed rofi themes. # This fills in #themes array and formats a displayable string #theme_names ## function find_themes() { DIRS=${XDG_DATA_DIRS} OLDIFS=${IFS} IFS=: if [ -z "${XDG_DATA_DIRS}" ] then echo "XDG_DATA_DIRS needs to be set for this script to function correctly." echo -n "Using dirs from \$PATH: " DIRS= # Iterate over items in $PATH for p in ${PATH}; do # Remove trailing / if exists. x=${p%/} # remove both /bin and /sbin and /games from end x=${x%/bin} x=${x%/sbin} x=${x%/games} # Add /share x=${x}/share # Check if entry exists Prepend : so :${x}: matches nicely case ":${DIRS}" in *$x:*);; *) DIRS+="$x:";; esac done # Remove trailing : DIRS=${DIRS%:} echo "${DIRS}" fi # Add user dir. DIRS+=":${HOME}/.local/share/" for p in ${DIRS}; do p=${p%/} TD=${p}/rofi/themes if [ -n "${p}" ] && [ -d "${TD}" ] then echo "Checking themes in: ${TD}" for file in ${TD}/*.rasi do if [ -f "${file}" ] then themes+=(${file}) FN=$(basename ${file}) NAME=${FN%.*} USER=$(${SED} -n 's/^.*User: \(.*\)/\1/p' ${file} | head -n 1 ) if [ -z "${USER}" ] then theme_names+=(${NAME}) else theme_names+=("${NAME} by ${USER}") fi fi done fi done IFS=${OLDIFS} } ## # Create a copy of rofi ## function create_config_copy() { ${ROFI} -dump-xresources > ${TMP_CONFIG_FILE} } ### # Print the list out so it can be displayed by rofi. ## function create_theme_list() { OLDIFS=${IFS} IFS='|' for themen in ${theme_names[@]} do echo ${themen} done IFS=${OLDIFS} } ## # Thee indicate what entry is selected. ## declare -i SELECTED function select_theme () { local MORE_FLAGS=(-dmenu -format i -no-custom -p "Theme" -markup -config ${TMP_CONFIG_FILE} -i) MORE_FLAGS+=(-kb-custom-1 "Alt-a") MORE_FLAGS+=(-u 2,3 -a 4,5 ) local CUR="default" while true do declare -i RTR declare -i RES local MESG="""You can preview themes by hitting Enter. Alt-a to accept the new theme. Escape to cancel Current theme: ${CUR}""" THEME_FLAG= if [ -n "${SELECTED}" ] then THEME_FLAG="-theme ${themes[${SELECTED}]}" fi RES=$( create_theme_list | ${ROFI} ${THEME_FLAG} ${MORE_FLAGS[@]} -cycle -selected-row "${SELECTED}" -mesg "${MESG}") RTR=$? if [ ${RTR} = 10 ] then return 0; elif [ ${RTR} = 1 ] then return 1; fi CUR=${theme_names[${RES}]} SELECTED=${RES} done } ### # Create if not exists, then removes #include of .theme file (if present) and add the selected theme to the end. # Repeated calls should leave the config clean-ish ### function set_theme() { CDIR="${HOME}/.config/rofi/" if [ ! -d "${CDIR}" ] then mkdir -p ${CDIR} fi if [ -f "${CDIR}/config.rasi" ] then ${SED} -i "/@import.*/d" "${CDIR}/config.rasi" echo "@import \"${1}\"" >> "${CDIR}/config.rasi" else if [ -f "${CDIR}/config" ] then ${SED} -i "/rofi\.theme: .*\.rasi$/d" "${CDIR}/config" fi echo "rofi.theme: ${1}" >> "${CDIR}/config" fi } ############################################################################################################ # Actual program execution ########################################################################################################### ## # Find all themes ## find_themes ## # Do check if there are themes. ## if [ ${#themes[@]} = 0 ] then ${ROFI} -e "No themes found." exit 0 fi ## # Create copy of config to play with in preview ## create_config_copy ## # Show the themes to user. ## if select_theme && [ -n "${SELECTED}" ] then # Set theme set_theme "${themes[${SELECTED}]}" fi ## # Remove temp. config. ## rm ${TMP_CONFIG_FILE}