dotfiles/styler/.local/bin/styler
Marty Oehme edfb305ef3 Add theme function
The theme function provides a quick but temporary switch to a specific
theme.

Themes can be applied with `styler theme [themename]`, they will be
instantly applied to all enabled applications. They will be lost on
restarts of the application or machine however.

Themes can be applied permanently with `styler set [themename]`, they
will be written into the application's settings. This *will* change
things in your local filesystem, so be wary. Generally, processors
should take the least invasive approach and use inclusion to append the
theme to the application's other settings.

But be *careful* with this option, and when in doubt double-check what
the processors you have installed do before losing your settings.
2020-02-01 11:00:29 +01:00

212 lines
6.1 KiB
Bash
Executable file

#!/usr/bin/env bash
readonly BASE_PATH="${STYLER_DATA_PATH:-${XDG_DATA_HOME:-$HOME/.local/share}/styler}"
readonly PACKAGE_PATH="$BASE_PATH/packages"
readonly PROCESSOR_PATH="$BASE_PATH/processors"
readonly VERSION="0.3.0"
main() {
local cmd=""
local ret=0
case "$1" in
-t | --theme | theme)
cmd="switch_theme"
;;
-s | --set | set)
cmd="set_theme"
;;
-l | --list | list)
cmd="list"
;;
-d | --download | download)
cmd="download"
;;
-v | --version | version)
printf "Program theming script.\n\n©Marty Oehme\n\nVersion: %s\n" "$VERSION"
exit 0
;;
-h | --help | help | *)
cmd="usage"
;;
esac
shift
$cmd "$1"
ret=$((ret + $?))
exit $ret
}
usage() {
printf "%s\n" \
"" \
" styler - Quickly switch your linux style." \
" Uses base16 themes to quickly set them for a variety of applications." \
"" \
" Usage: styler [-hv | set base16-themename]" \
"" \
" Options:" \
"" \
" -t | theme Temporarily switch theme. Use any valid base16 theme name (without base16- prefix)." \
" Theme will be lost upon restart, or application restarts." \
"" \
" -s | set Set the theme. Use any valid base16 theme name (without base16- prefix)." \
" Same as 'theme' option, but changes will be made permanent." \
"" \
" -d | download Download a base16 template into the package directory or download a processor16" \
" into the processor directory. Use user/repo format to automatically pull from github." \
"" \
" -h | help Print out this help." \
"" \
" -v | version Print out program information." \
"" \
""
}
# base directory should always exist
base_dir_exists_or_create() {
[[ -d "$BASE_PATH" ]] || mkdir "$BASE_PATH"
[[ -d "$PACKAGE_PATH" ]] || mkdir "$PACKAGE_PATH"
[[ -d "$PROCESSOR_PATH" ]] || mkdir "$BASE_PATH"
}
# retrieves all relevant packages from BASE_PATH/packages
# 'relevant' here means they follow github pattern of author/repository
get_packages() {
for author in "$PACKAGE_PATH"/*; do
# TODO should eventually be used to either distinguish between author/pkg and pkg packages
# or to spit out a warning if they should not be used.
# if grep -q -e '^base16-' <<<"$(basename -- "$author")"; then
# echo ERROR
# fi
for package in "$author"/*; do
[[ -e "$author" ]] || break
[[ -d "$package" ]] || break
printf "%s/%s\n" "$(basename -- "$author")" "$(basename -- "$package")"
done
done
}
# retrieves all processors from BASE_PATH/processors
# 'relevant' here means they follow github pattern of author/repository
get_processors() {
for author in "$PROCESSOR_PATH"/*; do
for package in "$author"/*; do
for processor in "$package"/*; do
[[ -e "$processor" ]] || break
[[ -f "$processor" ]] || break
if grep -q -e '/theme_[[:alnum:]]\{1,\}$' <<<"$processor"; then
printf "%s\n" "$(basename -- "$processor")"
fi
done
done
done
}
# retrieves all installed themes from all packages, appends applications they exist for
get_themes() {
local themes
themes=$(find "$PACKAGE_PATH" -type f -name 'base16-*')
echo "$themes" | sed "s/.*\\/base16-//" | sed "s/\\..*//" | sort | uniq
}
# temporarily switch theme, same thing as setting, only with permanence flag turned off for processors
switch_theme() {
set_theme "$1" "false"
}
# call processors for all installed packages
set_theme() {
local theme="$1"
local permanent="${2:-true}"
local packages
packages="$(get_packages)"
if [[ -z "$packages" ]]; then
printf "ERROR: No base16 packages installed. Please install at least 1 base16 package in %s/.\n" "$PACKAGE_PATH" >&2
exit 1
fi
local processors
processors="$(get_processors)"
if [[ -z "$processors" ]]; then
printf "ERROR: No application processors installed. Please install at least one processor in %s/.\n" "$PROCESSOR_PATH" >&2
exit 1
fi
for pkg in $packages; do
local appext
# filter the application a package targets, since base16 packages
# carry standard names this removes everything before base16-
# the result is the application it targets
# shellcheck disable=SC2001
appext=$(sed "s|^[[:alnum:]]\{1,\}/base16-||" <<<"$pkg")
# Compares application extension with existing processors and runs the appropriate processor if found
processor=$(find "$PROCESSOR_PATH" -type f -name "theme_$appext")
if [[ -f "$processor" ]]; then
"$processor" "$PACKAGE_PATH" "$pkg" "$theme" "$permanent"
else
printf "WARN: No processor found for application %s in %s. Make sure you install a processor for the application.\n" "$appext" "$PROCESSOR_PATH/" >&2
fi
done
}
list() {
local selected="$1"
case "$selected" in
packages)
get_packages
;;
processors)
get_processors
;;
themes)
get_themes
;;
*)
echo "Please select one of packages | processors | themes to list."
;;
esac
}
download() {
local pkg="$1"
local page="https://github.com"
local repo="$page/$pkg"
[[ -z "$pkg" ]] && {
echo "No package to download passed in. Please provide a package to download in the form user/repository."
exit 1
}
type git >/dev/null 2>&1 || {
echo "git is required to clone base16 package. Please install git."
exit 1
}
base_dir_exists_or_create
if ! git ls-remote --exit-code -h "$repo" >/dev/null; then
echo "Repository $repo not found."
exit 1
fi
# if package has patter name/base16-program, put it in packages; if name/process16-program put it in processors
# if none of the above, assume it's a processor but warn the user
if grep -q -e '^[0-9A-Za-z-]\{1,\}/base16-[0-9A-Za-z-]\{1,\}$' <<<"$pkg"; then
git clone "$repo" "$PACKAGE_PATH/$pkg"
elif grep -q -e '^[0-9A-Za-z-]\{1,\}/process16-[0-9A-Za-z-]\{1,\}$' <<<"$pkg"; then
git clone "$repo" "$PROCESSOR_PATH/$pkg"
else
echo "Package does not fit default naming scheme of packages/processors. Assuming it is a processor but please check manually."
git clone "$repo" "$PROCESSOR_PATH/$pkg"
fi
}
main "$@"