Marty Oehme
d8b5c067fb
rg does not give noticeable speed improvements, simply remove the command from styler and stick wich grep for each use.
314 lines
9.3 KiB
Bash
Executable file
314 lines
9.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
readonly BASE_PATH="${STYLER_DATA_PATH:-${XDG_DATA_HOME:-$HOME/.local/share}/styler}"
|
|
readonly CACHE_PATH="${STYLER_CACHE_PATH:-${XDG_CACHE_HOME:-$HOME/.cache}/styler}"
|
|
|
|
readonly PACKAGE_PATH="$BASE_PATH/packages"
|
|
readonly PROCESSOR_PATH="$BASE_PATH/processors"
|
|
|
|
readonly VERSION="0.4.1"
|
|
|
|
main() {
|
|
local cmd=""
|
|
local ret=0
|
|
|
|
case "$1" in
|
|
theme)
|
|
cmd="switch_theme"
|
|
;;
|
|
set)
|
|
cmd="set_theme"
|
|
;;
|
|
list)
|
|
cmd="list"
|
|
;;
|
|
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 "$@"
|
|
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|theme base16-themename]" \
|
|
"" \
|
|
" Arguments:" \
|
|
"" \
|
|
" theme [theme] Temporarily switch theme. Use any valid base16 theme name (without base16- prefix)." \
|
|
" Theme will be lost upon restart, or application restarts." \
|
|
"" \
|
|
" set [theme] Set the theme. Use any valid base16 theme name (without base16- prefix)." \
|
|
" Same as 'theme' option, but changes will be made permanent." \
|
|
"" \
|
|
" list [processors|packages|themes] Print out all currently installed processors, templates, or themes from selection. " \
|
|
" list themes Will print out themes which are available for all installed packages." \
|
|
" list themes all Will print out every single installed theme, regardless of its universal availability." \
|
|
"" \
|
|
" download [username/repository] 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." \
|
|
"" \
|
|
" help | -h | --help Print out this help." \
|
|
"" \
|
|
" version | -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 available to all packages
|
|
# can be called with `all` argument to return themes which only exist for some packages
|
|
get_themes() {
|
|
local themes
|
|
themes=$(find "$PACKAGE_PATH" -type f -name 'base16-*')
|
|
|
|
local filtered
|
|
if [[ "$1" = "all" ]]; then
|
|
filtered="$(get_unique_themes "$themes")"
|
|
else
|
|
filtered="$(get_universal_themes "$themes")"
|
|
fi
|
|
|
|
echo "$filtered"
|
|
}
|
|
|
|
# filter down the list passed in to keep repeating base16 themes only once per name
|
|
# and remove surrounding path information (and file ending)
|
|
get_unique_themes() {
|
|
if _cache_invalid "$CACHED_UNIQUE_THEMES" "$PACKAGE_PATH"; then
|
|
notify-send "styler cache invalid" "rebuilding cache will take a moment..."
|
|
_cache_rebuild "$CACHED_UNIQUE_THEMES" _fetch_unique_themes "$@"
|
|
else
|
|
cat "$CACHED_UNIQUE_THEMES"
|
|
fi
|
|
}
|
|
readonly CACHED_UNIQUE_THEMES=${CACHE_PATH}/unique_themes
|
|
|
|
# returns themes which are available in all installed packages
|
|
# returns cached version or rebuilds cache
|
|
get_universal_themes() {
|
|
if _cache_invalid "$CACHED_UNIVERSAL_THEMES" "$PACKAGE_PATH"; then
|
|
notify-send "styler cache invalid" "rebuilding cache will take a moment..."
|
|
_cache_rebuild "$CACHED_UNIVERSAL_THEMES" _fetch_universal_themes "$@"
|
|
else
|
|
cat "$CACHED_UNIVERSAL_THEMES"
|
|
fi
|
|
}
|
|
readonly CACHED_UNIVERSAL_THEMES=${CACHE_PATH}/universal_themes
|
|
|
|
_fetch_unique_themes() {
|
|
echo "$1" | sed "s/.*\\/base16-//;s/\\..*//" | sort | uniq
|
|
}
|
|
|
|
# only keep themes which are available in every installed package
|
|
_fetch_universal_themes() {
|
|
local themes="$1"
|
|
local unique
|
|
unique="$(get_unique_themes "$themes")"
|
|
|
|
local packages
|
|
packages="$(get_packages)"
|
|
|
|
local filtered
|
|
for t in $unique; do
|
|
for p in $packages; do
|
|
if ! echo "$themes" | grep -qe "^.*$p.*$t.*$" -; then
|
|
themes="$(echo "$themes" | sed "/$t/d")"
|
|
unique="$(echo "$unique" | sed "/$t/d")"
|
|
break
|
|
fi
|
|
done
|
|
done
|
|
echo "$unique"
|
|
}
|
|
|
|
# returns true if changes to $2 are newer than $1
|
|
# used to pass in cache file for $1, what it is caching for $2
|
|
_cache_invalid() {
|
|
cache_upd="$(_last_update "$1")"
|
|
live_upd="$(_last_update "$2")"
|
|
if [ "${live_upd%.*}" -gt "${cache_upd%.*}" ]; then
|
|
true
|
|
else
|
|
false
|
|
fi
|
|
}
|
|
|
|
# recreates target cache with output of function
|
|
# arguments: "target_cache_file" "function_name" "arguments_for_function"
|
|
_cache_rebuild() {
|
|
local target="$1"
|
|
shift
|
|
local fct="$1"
|
|
shift
|
|
local new
|
|
new="$($fct "$@")"
|
|
mkdir -p "$CACHE_PATH"
|
|
echo "$new" | tee "$target"
|
|
}
|
|
|
|
# returns time of last update to argument passed in
|
|
# argument can be path to file or directory (searched recursively)
|
|
# if argument does not exist gives 0
|
|
_last_update() {
|
|
[[ ! -e "$1" ]] && echo 0 && return
|
|
find "$1" -type f -printf "%T@\n" | sort -n | tail -n 1
|
|
}
|
|
|
|
# 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"
|
|
if [[ -z $theme ]]; then
|
|
printf "Theme application requires an argument.\n"
|
|
exit 1
|
|
fi
|
|
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 -e 's|^[A-Za-z0-9-]\{1,\}/base16-||' <<<"$pkg")
|
|
|
|
# Compares application extension with existing processors and runs the appropriate processor if found
|
|
processor=$(find "$PROCESSOR_PATH" -type f | grep -e "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"
|
|
shift
|
|
|
|
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 "$@"
|