1#!/usr/bin/env bash 2# 3# This code is released in public domain by Dave Davenport <qball@gmpclient.org> 4# 5 6 7ROFI=$(which rofi) 8SED=$(which sed) 9MKTEMP=$(which mktemp) 10 11if [ -z "${SED}" ] 12then 13 echo "Did not find 'sed', script cannot continue." 14 exit 1 15fi 16if [ -z "${MKTEMP}" ] 17then 18 echo "Did not find 'mktemp', script cannot continue." 19 exit 1 20fi 21if [ -z "${ROFI}" ] 22then 23 echo "Did not find rofi, there is no point to continue." 24 exit 1 25fi 26 27TMP_CONFIG_FILE=$(${MKTEMP}).rasi 28 29## 30# Array with parts to the found themes. 31# And array with the printable name. 32## 33declare -a themes 34declare -a theme_names 35 36## 37# Function that tries to find all installed rofi themes. 38# This fills in #themes array and formats a displayable string #theme_names 39## 40function find_themes() 41{ 42 DIRS=${XDG_DATA_DIRS} 43 OLDIFS=${IFS} 44 IFS=: 45 if [ -z "${XDG_DATA_DIRS}" ] 46 then 47 echo "XDG_DATA_DIRS needs to be set for this script to function correctly." 48 echo -n "Using dirs from \$PATH: " 49 DIRS= 50 # Iterate over items in $PATH 51 for p in ${PATH}; do 52 # Remove trailing / if exists. 53 x=${p%/} 54 # remove both /bin and /sbin and /games from end 55 x=${x%/bin} 56 x=${x%/sbin} 57 x=${x%/games} 58 # Add /share 59 x=${x}/share 60 # Check if entry exists Prepend : so :${x}: matches nicely 61 case ":${DIRS}" in 62 *$x:*);; 63 *) DIRS+="$x:";; 64 esac 65 done 66 # Remove trailing : 67 DIRS=${DIRS%:} 68 echo "${DIRS}" 69 fi 70 # Add user dir. 71 DIRS+=":${XDG_DATA_HOME:-${HOME}/.local/share}" 72 DIRS+=":${XDG_CONFIG_HOME:-${HOME}/.config}" 73 for p in ${DIRS}; do 74 p=${p%/} 75 TD=${p}/rofi/themes 76 if [ -n "${p}" ] && [ -d "${TD}" ] 77 then 78 echo "Checking themes in: ${TD}" 79 for file in ${TD}/*.rasi 80 do 81 if [ -f "${file}" ] 82 then 83 themes+=(${file}) 84 FN=$(basename ${file}) 85 NAME=${FN%.*} 86 USER=$(${SED} -n 's/^.*User: \(.*\)/\1/p' ${file} | head -n 1 ) 87 if [ -z "${USER}" ] 88 then 89 theme_names+=(${NAME}) 90 else 91 theme_names+=("${NAME} by ${USER}") 92 fi 93 fi 94 done 95 fi 96 done 97 IFS=${OLDIFS} 98 99} 100 101## 102# Create a copy of rofi 103## 104function create_config_copy() 105{ 106 ${ROFI} -dump-config > ${TMP_CONFIG_FILE} 107 # remove theme entry. 108 sed -i 's/^\s*theme:\s\+".*"\s*;//g' ${TMP_CONFIG_FILE} 109} 110 111### 112# Print the list out so it can be displayed by rofi. 113## 114function create_theme_list() 115{ 116 OLDIFS=${IFS} 117 IFS='|' 118 for themen in ${theme_names[@]} 119 do 120 echo ${themen} 121 done 122 IFS=${OLDIFS} 123} 124 125## 126# Thee indicate what entry is selected. 127## 128declare -i SELECTED 129 130function select_theme () 131{ 132 local MORE_FLAGS=(-dmenu -format i -no-custom -p "Theme" -markup -config ${TMP_CONFIG_FILE} -i) 133 MORE_FLAGS+=(-kb-custom-1 "Alt-a") 134 MORE_FLAGS+=(-u 2,3 -a 4,5 ) 135 local CUR="default" 136 while true 137 do 138 declare -i RTR 139 declare -i RES 140 local MESG="""You can preview themes by hitting <b>Enter</b>. 141<b>Alt-a</b> to accept the new theme. 142<b>Escape</b> to cancel 143Current theme: <b>${CUR}</b>""" 144 THEME_FLAG= 145 if [ -n "${SELECTED}" ] 146 then 147 THEME_FLAG="-theme ${themes[${SELECTED}]}" 148 fi 149 RES=$( create_theme_list | ${ROFI} ${THEME_FLAG} ${MORE_FLAGS[@]} -cycle -selected-row "${SELECTED}" -mesg "${MESG}") 150 RTR=$? 151 if [ ${RTR} = 10 ] 152 then 153 return 0; 154 elif [ ${RTR} = 1 ] 155 then 156 return 1; 157 elif [ ${RTR} = 65 ] 158 then 159 return 1; 160 fi 161 CUR=${theme_names[${RES}]} 162 SELECTED=${RES} 163 done 164} 165 166### 167# Create if not exists, then removes #include of .theme file (if present) and add the selected theme to the end. 168# Repeated calls should leave the config clean-ish 169### 170function set_theme() 171{ 172 CDIR="${XDG_CONFIG_HOME:-${HOME}/.config}/rofi" 173 if [ ! -d "${CDIR}" ] 174 then 175 mkdir -p ${CDIR} 176 fi 177 if [ -f "${CDIR}/config.rasi" ] 178 then 179 get_link=$(readlink -f "${CDIR}/config.rasi") 180 ${SED} -i "" "/@import.*/d" "${get_link}" 181 echo "@import \"${1}\"" >> "${get_link}" 182 else 183 if [ ! -e "${CDIR}/config" ] 184 then 185 # No file. 186 echo "rofi.theme: ${1}" >> "${CDIR}/config" 187 elif [ -f "${CDIR}/config" ] 188 then 189 # Regular file 190 get_link=$(readlink -f "${CDIR}/config") 191 ${SED} -i "" "/rofi\.theme: .*\.rasi$/d" "${get_link}" 192 echo "rofi.theme: ${1}" >> "${get_link}" 193 fi 194 fi 195} 196 197############################################################################################################ 198# Actual program execution 199########################################################################################################### 200## 201# Find all themes 202## 203find_themes 204 205## 206# Do check if there are themes. 207## 208if [ ${#themes[@]} = 0 ] 209then 210 ${ROFI} -e "No themes found." 211 exit 0 212fi 213 214## 215# Create copy of config to play with in preview 216## 217create_config_copy 218 219## 220# Show the themes to user. 221## 222if select_theme && [ -n "${SELECTED}" ] 223then 224 # Set theme 225 set_theme "${themes[${SELECTED}]}" 226fi 227 228## 229# Remove temp. config. 230## 231rm ${TMP_CONFIG_FILE} 232