#!/usr/bin/env sh progname="$(basename "$0")" data="$(dirname "$(readlink -f "$0")")" export data # path to directory containing reload.d, switch.d, etc. run_switch=1 run_reload=1 no_cfg=0 theme="" # absolute path to theme # print error message and exit with error stupid() { echo "$@" >&2 echo "run \`$progname --help\` for options" >&2 exit 1 } usage() { cat << EOF $progname -- switch system themes usage: $progname [-chr] action|theme options: -s, --no-switch disable running switch.d hooks -c, --no-cfggen disable generation of templated configuration files -h, --help display this help text -r, --no-reload disable reloading of applications after applying theme actions: restore switch to last set theme ($XDG_CACHE_HOME/mode/state/theme) reload do not update configuration files, only reload applications help same as --help option list list all themes examples: mode dark switch to dark mode and reload applications mode restore --no-reload make sure all configuration files are up-to-date mode reload only reload applications EOF } # run a module file run_mod() { mod_name="$1" # modules must be executable ! [ -x "$mod_name" ] && return # parse interpreter from shebang interpreter="$(basename "$(command -v $(head -n1 "$mod_name" | sed -n 's/^#!\(.*\)/\1/p'))")" if [ "$interpreter" = "sh" ] ; then # source module if interpreter is POSIX sh (makes plugin functions available) ( . "$mod_name" ) else # else, just run them "$mod_name" fi } # generate config files from theme file using scripts in switch.d switch() { [ -z "$theme" ] && stupid "error: no theme selected" [ ! -e "$theme" ] && stupid "error: theme not found" export theme theme_name="$(basename "$theme")" echo "setting theme to $theme_name..." # clean up environment unset accent accent_text unset mode # load theme colors + aux variables . "$theme" # load plugins (TODO: plugins aren't loaded when only reloading) for plugin in "$data"/plug.d/* ; do . "$plugin" ; done # generate new config files / snippets (in parallel) for switch_function in "$data"/switch.d/* ; do run_mod "$switch_function" & done # join all processes started above wait $(jobs -p) } # reload programs using scripts in reload.d reload() { echo "reloading programs..." for reload_function in "$data"/reload.d/* ; do run_mod "$reload_function" & done wait $(jobs -p) } # main program argument parser (later argument always take priority) for arg in "$@" ; do case "$arg" in # stop parsing arguments after -- --) break ;; # help -h|--help|help) usage && exit 0 ;; # only run reload scripts reload) run_reload=1 run_switch=0 ;; # prevent reload.d scripts from running -r|--no-reload) run_reload=0 ;; # prevent switch.d scripts from running -s|--no-switch) run_switch=0 ;; # prevent switch.d scripts from running -c|--no-cfggen) no_cfg=1 ;; # restore previous theme stored as symlink (see switch.d/mode) restore) theme="$(readlink -f "$XDG_CACHE_HOME/mode/state/theme")" [ ! -e "$theme" ] && stupid "error: could not locate previous theme" ;; # list themes in themes folder list) find "$data/themes" -type f,l | while read -r theme ; do printf '%s' "$(basename "$theme")" link="$(readlink "$theme")" && printf ' (%s)' "$link" printf '\n' done exit 0 ;; *) # check if unknown argument is a theme name if [ -e "$data/themes/$arg" ] ; then theme="$(readlink -f "$data/themes/$arg")" continue fi # else throw error stupid "error: unknown argument or theme: $arg" ;; esac done export no_cfg # main [ $run_switch -eq 1 ] && switch [ $run_reload -eq 1 ] && reload