Compare commits

...

13 Commits

Author SHA1 Message Date
85509d556c wip: hyprpaper_single.sh 2024-12-23 17:35:13 +03:00
9fd1a31bdb verify effects and do error reporting
sometimes GTK and gsettings can go crazy, untrackably.
more error messages i get, the better.
2024-10-31 10:48:58 +03:00
a6bc546570 should've checked before committing 2024-10-22 17:58:01 +03:00
7e300fc04e this'll work better ig 2024-10-22 17:52:52 +03:00
0602eb1bf7 update background logic
backgrounds saved for light/dark modes are now stored as the absolute
path, so config keys chore.bg_dark and chore.bg_light now contain the
string of absolute path to image files.

in addition to this update, swww_single chore now copies the current
background image to the location of chore.current_bg, which can be used
to directly access the image of the current background.
2024-10-22 16:58:40 +03:00
02fcdf794b pass $mode to reload, find real path even when sourcing 2024-10-10 10:20:47 +03:00
245dc99887 state man. API && modularisation
- adds functions
  - util_create_state
  - util_read_state
  - util_write_state
  - util_delete_state
for state management API. see docs/about_states.md for details.

- moves functions from _reve.sh to _reve_utils.sh to prevent circular
imports.
2024-10-09 20:01:30 +03:00
dd663f47a0 small typo fixed 2024-10-02 22:23:38 +03:00
49c80b4b3d improved dm logic, bug fix for mode subcommand 2024-10-02 22:18:38 +03:00
8f5225cb23 add mode chore nvim_theme, update example mode chore 2024-10-02 21:53:18 +03:00
e4917fddec small typo 2024-10-02 21:46:54 +03:00
967f3c50e4 update and chores subcommands added
+ update all chores from upstream
+ list, add and remove chores
2024-10-02 21:46:02 +03:00
b6bac4bbdc formatting <<< moving 2 spaces to left <<< 2024-10-02 17:46:46 +03:00
17 changed files with 601 additions and 222 deletions

View File

@@ -7,16 +7,13 @@
reve_installation="$HOME/.local/bin/reve"
reve_config="$HOME/.config/reve"
util_readf() {
local filename=$1
if [[ -f "$filename" ]]; then
cat "$filename"
else
error E "util_readf" "File not found: $filename"
return 1
fi
}
_current_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
# shellcheck source=_reve_states.sh
source "$_current_dir/_reve_states" >&/dev/null
(($? == 1)) && source "$_current_dir/_reve_states.sh"
# shellcheck source=_reve_utils.sh
source "$_current_dir/_reve_utils" >&/dev/null
(($? == 1)) && source "$_current_dir/_reve_utils.sh"
util_where_config() {
local config_key=$1
@@ -69,7 +66,7 @@ util_run_utility() {
}
reload() {
util_run_chore "$1"
util_run_chore "$1" "$2"
}
reload_util() {
@@ -83,11 +80,3 @@ util_toggle_dm() {
util_write_config base.desktop_mode dark
fi
}
error() {
local level=$1 location=$2 cause=$3
message="[reve] [$level] [$location] $cause"
echo "$message"
now=$(date -Iminutes)
echo "${now::-6} $message" >>"$reve_installation/reve.log"
}

99
_reve_states.sh Normal file
View File

@@ -0,0 +1,99 @@
#!/usr/bin/env bash
# reve desktop environment framework
# Yigid BALABAN <fyb@fybx.dev> 2024
# reve internal: _reve_states
# defines state management API
_current_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
# shellcheck source=_reve_utils.sh
source "$_current_dir/_reve_utils" >&/dev/null
(($? == 1)) && source "$_current_dir/_reve_utils.sh"
REVE_STATE_REPO="$HOME/.local/bin/reve/states"
__util_pathto_state() {
# args: $1 -- state key
# args: $2 -- state type
local key=$1 type=$2
pre_removed_key=${key/#base./}
state_path="$(echo "$pre_removed_key" | sed 's/\./\//g')$type"
echo "$state_path"
}
__util_find_state() {
# args: $1 -- state key
# returns: 1 if state key not in map
# 2 if map is corrupted
local key=$1
type=$(awk -F'=' -v key="$key" '$1 == key {print $2}' "$REVE_STATE_REPO/map")
case "$type" in
prs | persistent) type="" ;;
tmp | temporary) type=".tmp" ;;
"")
error E states "state referenced by key '$key' doesn't exist"
return 1
;;
*)
error E states "state map '$REVE_STATE_REPO/map' is corrupted"
return 2
;;
esac
__util_pathto_state "$1" "$type"
}
util_create_state() {
local type=$1 key=$2 value=$3
if [ "$type" != "tmp" ] && [ "$type" != "prs" ]; then
error E util_create_state "can't create state with type '$type'"
return
fi
if ! __util_find_state "$key"; then
echo "$value" >"$(__util_pathto_state "$key" "$type")"
echo "$key=$value" >"$REVE_STATE_REPO/map"
fi
}
util_write_state() {
local key=$1 value=$2
_path=$(__util_find_state "$key")
if $? -eq 0; then
echo "$value" >"$_path"
fi
}
util_read_state() {
local key=$1
_path=$(__util_find_state "$key")
if $? -eq 0; then
cat "$_path"
fi
}
util_delete_state() {
local key=$1
_path=$(__util_find_state "$key")
if $? -eq 0; then
rm "$_path"
awk -F '=' -v key="$key" '$1 != key' "$REVE_STATE_REPO/map" >"$REVE_STATE_REPO/map.tmp"
mv "$REVE_STATE_REPO/map.tmp" "$REVE_STATE_REPO/map"
_dir=$(dirname "$_path")
[ -z "$(ls -A "$_dir")" ] && rm -r "$_dir"
fi
}
util_deleteall_temp() {
awk -F'=' '$2 == "tmp" { print $1 }' data.txt | while read -r key; do
util_delete_state "$key"
done
}

29
_reve_utils.sh Normal file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# reve desktop environment framework
# Yigid BALABAN <fyb@fybx.dev> 2024
# reve internal: _reve_utils
# defines utility functions
# VERY CRITICAL: change this if install.sh is updated
reve_installation="$HOME/.local/bin/reve"
util_readf() {
local filename=$1
if [[ -f "$filename" ]]; then
cat "$filename"
else
error E "util_readf" "File not found: $filename"
return 1
fi
}
error() {
local level=$1 location=$2 cause=$3
message="[reve] [$level] [$location] $cause"
echo "$message"
now=$(date -Iminutes)
echo "${now::-6} $message" >>"$reve_installation/reve.log"
}

27
chores/misc/asus_kbd_light.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# reve desktop environment framework
# Yigid BALABAN <fyb@fybx.dev> 2024
# chore script
# type misc
# name asus_kbd_light.sh
# desc ...
# vars ...
# reload ...
reve_folder="$HOME/.config/reve"
reve_desktop_mode="$reve_folder/desktop_mode"
source "$( reve -w )/_reve"
current_mode=$( util_readf "$reve_desktop_mode" )
if [ "$current_mode" == "light" ]; then
exit 0
fi
hex_dominant_color=$( magick "$reve_folder/chore/bg_dark" -resize 1x1\! -format "%[hex:p{0,0}]" info: )
asusctl led-mode static -c "$hex_dominant_color"
asusctl --kbd-bright med

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# reve desktop environment framework
# Yigid BALABAN <fyb@fybx.dev> 2024
# chore script
# type mode
# name display_brightness.sh
# desc sets display brightness depending on the desktop_mode
# vars day_level, night_level
# reload none
# shellcheck source=../../_reve.sh
source "$(reve where)/_reve"
if [ "$RV_CURRENT_MODE" == "dark" ]; then
brightnessctl set "$(util_read_config display.night_level)"
else
brightnessctl set "$(util_read_config display.day_level)"
fi

View File

@@ -12,5 +12,16 @@
# shellcheck source=../../_reve.sh
source "$(reve where)/_reve"
gsettings set org.gnome.desktop.interface gtk-theme "$(util_read_config chore.gtk_"$RV_CURRENT_MODE"_theme)"
gsettings set org.gnome.desktop.interface color-scheme prefer-"$RV_CURRENT_MODE"
key="org.gnome.desktop.interface"
target_theme="$(util_read_config chore.gtk_"$RV_CURRENT_MODE"_theme)"
target_scheme="prefer-$RV_CURRENT_MODE"
if ! gsettings set "$key" gtk-theme "$target_theme" ||
[ "$(gsettings get "$key" gtk-theme | tr -d \')" != "$target_theme" ]; then
error E mode/gtk-theme "Could not set gtk-theme to: $target_theme"
fi
if ! gsettings set "$key" color-scheme "$target_scheme" ||
[ "$(gsettings get "$key" color-scheme | tr -d \')" != "$target_scheme" ]; then
error E mode/gtk-theme "Could not set color-scheme to: $target_scheme"
fi

View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
# reve desktop environment framework
# Yigid BALABAN <fyb@fybx.dev> 2024
# chore script
# type mode
# name hyprpaper_single.sh
# desc changes the background depending on the desktop_mode
# vars bg_dark, bg_light
# reload none
if ! command -v hyprpaper &>/dev/null; then
echo "hyprpaper is not installed. Please install it and try again."
exit 1
fi
# shellcheck source=../../_reve.sh
source "$(reve where)/_reve"
bg="$(util_read_config chore."bg_$RV_CURRENT_MODE")"
current_bg="$(util_where_config chore.current_bg)"
# Only change if different from current
if [ "$bg" != "$(readlink -f "$current_bg")" ]; then
hyprctl hyprpaper preload "$bg"
hyprctl hyprpaper wallpaper ",${bg}"
hyprctl hyprpaper unload unused
cp "$bg" "$current_bg"
notify-send --urgency=low --expire-time=1450 --icon="$bg" \
--app-name="reve: hyprpaper_single" \
"Wallpaper changed" \
"Wallpaper changed and saved on $RV_CURRENT_MODE mode."
fi

View File

@@ -17,4 +17,4 @@ if ! command -v kitty &>/dev/null; then
exit 1
fi
kitten themes --reload-in=all "$(util_read_config chore.kitty."$RV_CURRENT_THEME")"
kitten themes --reload-in=all "$(util_read_config chore.kitty."$RV_CURRENT_MODE")"

20
chores/mode/nvim_theme.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
# reve desktop environment framework
# Yigid BALABAN <fyb@fybx.dev> 2024
# chore script
# type mode
# name nvim_theme.sh
# desc sends a signal to nvim to fetch desktop_mode
# vars none
# reload none
handle_usr1() {
return
}
trap handle_usr1 USR1
if pids=$(pgrep -f 'nvim'); then
echo "$pids" | xargs kill -USR1
fi

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# reve desktop environment framework
# Yigid BALABAN <fyb@fybx.dev> 2024
@@ -23,7 +23,8 @@ ltypes=${#types[@]}
rindex=$((RANDOM % ltypes))
rtype=${types[rindex]}
bg="$(util_where_config chore."bg_$RV_CURRENT_MODE")"
bg="$(util_read_config chore."bg_$RV_CURRENT_MODE")"
swww img --transition-type "$rtype" --transition-pos 1,1 --transition-step 90 "$bg"
notify-send --urgency=low --expire-time=1450 --icon="$bg" --app-name="reve: swww_single" "Wallpaper changed" "Wallpaper changed and saved on light mode."
notify-send --urgency=low --expire-time=1450 --icon="$bg" --app-name="reve: swww_single" "Wallpaper changed" "Wallpaper changed and saved on $RV_CURRENT_MODE mode."
cp "$bg" "$(util_where_config chore.current_bg)"
reload misc/asus_kbd_light.sh

22
chores/mode/swww_slideshow.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
# reve desktop environment framework
# Yigid BALABAN <fyb@fybx.dev> 2024
# chore script
# type mode
# name swww-based wallpaper slideshow
# desc reruns utility/swww_slideshow when mode changes
# vars swwwss.dark, swwwss.light, swwwss.folder
# reload no
# shellcheck source=../../_reve.sh
source "$(reve where)/_reve"
desktop_mode=$(util_read_config base.desktop_mode)
if [ "$desktop_mode" == "dark" ]; then
util_write_config swwwss.folder "$(util_read_config swwwss.dark)"
else
util_write_config swwwss.folder "$(util_read_config swwwss.light)"
fi

0
chores/power/laptop_disp_rr.sh Executable file
View File

26
docs/about_states.md Normal file
View File

@@ -0,0 +1,26 @@
# reve docs
"about states", revision 1
yigid balaban \<fyb@fybx.dev\>
## about states
different from configuration files, some information is temporary, and "local" to current runtime. some utilities, for example, may need a way to store and access variables. for that reason reve exposes 4 functions to work with states that can be temporary or permanent.
for this reason, states can be created/updated, deleted or read using reve.
### reve's API for states
Functions for working with states are defined in `_reve.sh`:
1. `util_create_state {type} {key} [value]`: Creates the state file. `{type}` can be `tmp` for temporary or `prs` for persistent.
1. `util_read_state {key}`: Returns the value read from file addressed by key. Will return `1` if an error occurs.
2. `util_write_state {key} {value}`: Writes the value to file addressed by key. Will **overwrite** without warning.
3. `util_delete_state {key}`: Deletes the file addressed by key. Will delete the containing folder, if the folder is empty.
### underlying implementation
- the `key`s are dot-delimited folders, subfolders and files. The last element of the key is assumed to be the file name.
- trying to read, write or delete a file that is not created will return an error.
- as a result of the rule above, writing a new state is not possible, you have to create it with an explicit type first.
- temporary states will be cleaned when the appropriate call is made (`reve state clean`)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
# reve desktop environment framework
# Yigid BALABAN <fyb@fybx.dev> 2024
@@ -8,11 +8,11 @@
# name chore_script.sh
# desc ...
# vars ...
# reload ...
reve_folder="$HOME/.config/reve"
reve_desktop_mode="$reve_folder/desktop_mode"
# shellcheck source=../_reve.sh
source "$(reve where)/_reve"
source "$( reve -w )/_reve"
echo "Hello, world! Current mode is $RV_CURRENT_MODE."
current_mode=$( util_readf "$reve_desktop_mode" )
echo "Hello, world! Current mode is $current_mode."
reload mode/gtk_theme

View File

@@ -11,11 +11,15 @@ reve_installation_target="$HOME/.local/bin/reve"
echo "[1/5] Creating reve installation folder"
mkdir -p "$reve_installation_target"
echo "[2/5] Copying: reve.sh and _reve.sh"
echo "[2/5] Copying: reve.sh and other internal tools"
cp reve.sh "$reve_installation_target/reve"
cp _reve.sh "$reve_installation_target/_reve"
cp _reve_utils.sh "$reve_installation_target/_reve_utils"
cp _reve_states.sh "$reve_installation_target/_reve_states"
chmod +x "$reve_installation_target/reve"
chmod -x "$reve_installation_target/_reve"
chmod -x "$reve_installation_target/_reve_utils"
chmod -x "$reve_installation_target/_reve_states"
echo "[3/5] Adding reve to path"
if grep -q "/bin/bash" /etc/shells; then

142
reve.sh
View File

@@ -10,7 +10,7 @@ in_desktop_mode=""
in_reason=""
in_chore_name=""
rt_script_dir=$(realpath "$(dirname "$0")")
rt_script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
rt_has_mode_changed=0
rt_current_mode="unset"
@@ -40,6 +40,7 @@ util_help () {
echo "== Subcommands =="
echo "1. config gets/sets configuration values"
echo "2. update updates chores"
echo "3. chores manages installed chores"
;;
config)
echo "=> Usage"
@@ -50,8 +51,19 @@ util_help () {
update)
echo "=> Usage: reve update [chore names...] updates chores from upstream"
echo "== Details =="
echo "Updates all chores present on your configuration if nothing is given. The"
echo "chore names must be space delimited."
echo "Updates all chores present on your installation if nothing is given."
echo "The chore names must be space delimited."
;;
chores)
echo "=> Usage"
echo "1. reve chores list lists all installed chores"
echo "2. reve chores add {chore_name} adds chore_name from .reve_repo"
echo "3. reve chores rm {chore_name} removes chore_name from installation"
echo "4. reve chores more lists chores available for installation"
echo "== Details =="
echo "'chore_name' must be a valid chore name like 'mode/gtk_theme', 'misc/foo'."
echo "The file extension (.sh) must be discarded."
echo "'.reve_repo' is managed by reve, and it's located in '\$reve_installation'."
;;
esac
}
@@ -73,13 +85,13 @@ f_shell_completion () {
}
set_desktop_mode() {
if [[ -n "$in_desktop_mode" ]]; then
echo "$in_desktop_mode" > "$reve_desktop_mode"
return 1 # since mode has changed
fi
local previous_mode num_day num_night current_time
previous_mode=$(util_read_config base.desktop_mode)
if [[ -n "$in_desktop_mode" ]]; then
rt_current_mode="$in_desktop_mode"
echo "$in_desktop_mode" >"$reve_desktop_mode"
else
num_day=$(awk -F: '{print $1 * 60 + $2}' <<<"$(util_read_config base.time_day)")
num_night=$(awk -F: '{print $1 * 60 + $2}' <<<"$(util_read_config base.time_night)")
current_time=$(awk -F: '{print $1 * 60 + $2}' <<<"$(date +%H:%M)")
@@ -89,10 +101,10 @@ set_desktop_mode () {
else
rt_current_mode="dark"
fi
echo "$rt_current_mode" >"$reve_desktop_mode"
fi
echo "[reve] [I] Setting the mode: $rt_current_mode"
echo "$rt_current_mode" > "$reve_desktop_mode"
if [ "$rt_current_mode" == "$previous_mode" ]; then
return 0 # since mode did not change
else
@@ -103,12 +115,7 @@ set_desktop_mode () {
# Called when the mode (the default state, is either dark or light) changes
chores_mode() {
for file in "$reve_chores_mode"/*; do
if [ -x "$file" ]; then
echo "[reve] [I] Running chore: $( basename "$file" )"
util_run_chore "$file" $rt_current_mode
else
echo "[reve] [E] chores_mode: $file is not executable"
fi
util_run_chore "mode/$(basename "${file%.sh}")" $rt_current_mode
done
}
@@ -126,6 +133,95 @@ util_handle_pos () {
echo $forced_mode
}
f_get_available_chores() {
c_ins=0
c_ble=0
while IFS= read -r file; do
file=${file#"$reve_installation/.reve_repo/chores/"} && file=${file%.sh}
if [ -f "$reve_installation/chores/$file.sh" ]; then
echo "$file"
((c_ins++))
else
echo "$file"
((c_ble++))
fi
done < <(find "$reve_installation/.reve_repo/chores" -type f -name "*.sh")
error I f_get_available_chores "$c_ins installed, $c_ble available"
}
f_add_chore() {
# args: $1 -- chore_name
# returns: 1 if error, otherwise 0
src_file="$reve_installation/.reve_repo/chores/$1.sh"
if [ -f "$src_file" ]; then
cp "$src_file" "$reve_installation/chores/$1.sh"
else
error E f_add_chore "there's no chore named '$1' in upstream"
return 1
fi
return 0
}
f_rm_chore() {
# args: $1 -- chore_name
# returns: 1 if error, otherwise 0
target_file="$reve_installation/chores/$1.sh"
if [ -f "$target_file" ]; then
rm "$target_file"
else
error E f_rm_chore "there's no chore named '$1' in installation"
return 1
fi
return 0
}
sub_chores() {
case $1 in
list)
echo "installed chores:"
find "$reve_installation/chores/" -type f -name "*.sh" | while read -r file; do
echo "$file" | awk -F/ '{print " -> "$(NF-1)"/"$NF}'
done
;;
more) f_get_available_chores ;;
add) f_add_chore $2 ;;
rm) f_rm_chore $2 ;;
esac
}
sub_update() {
local repo_dir="$reve_installation/.reve_repo"
local repo_url="https://git.fybx.dev/fyb/reve.git"
if [ ! -d "$repo_dir/.git" ]; then
error I reve "in sub_update, cloning repository"
git clone "$repo_url" "$repo_dir" &>/dev/null
else
error I reve "in sub_update, pulling changes"
git -C "$repo_dir" pull &>/dev/null
fi
if [ $# -eq 0 ]; then
error I sub_update "updating all chores"
count=0
find "$reve_installation/chores/" -type f -name "*.sh" | while read -r file; do
file="${file#"$reve_installation/chores/"}"
file="${file%".sh"}"
echo $file
# shellcheck disable=SC2030
f_add_chore "$file" && ((count++))
done
# shellcheck disable=SC2031
((count != 0)) && error I sub_update "copied $count files"
else
for arg in "$@"; do
f_add_chore "$arg"
done
fi
}
sub_config() {
case "$1" in
get)
@@ -168,7 +264,11 @@ case "$1" in
exit 0
;;
update)
sub_update
sub_update "${@:2}"
exit 0
;;
chores)
sub_chores "$2" "$3"
exit 0
;;
help)
@@ -184,6 +284,11 @@ case "$1" in
f_shell_completion
exit 0
;;
state)
if [ "$2" == "clean" ]; then
util_deleteall_temp
fi
;;
mode)
in_desktop_mode="$2"
;;
@@ -193,8 +298,7 @@ case "$1" in
chore)
in_chore_name="$2"
;;
poll)
;;
poll) ;;
"")
util_help "$2"
exit 0

View File

@@ -6,13 +6,10 @@
# cp utility/nemo/set_wallpaper.sh ~/.local/share/nemo/scripts
# chmod +x ~/.local/share/nemo/scripts/set_wallpaper.sh
# shellcheck source=../../_reve.sh
source "$(reve where)/_reve"
reve_folder="$HOME/.config/reve"
reve_desktop_mode="$reve_folder/desktop_mode"
mode=$(util_readf "$reve_desktop_mode")
bgl="$reve_folder/chore/bg_light"
bgd="$reve_folder/chore/bg_dark"
mode=$(util_read_config base.desktop_mode)
if [ "$NEMO_SCRIPT_SELECTED_FILE_PATHS" = "" ]; then
first=$1
@@ -20,10 +17,5 @@ else
first=$(echo "$NEMO_SCRIPT_SELECTED_FILE_PATHS" | head -n 1)
fi
if [ "$mode" = "dark" ]; then
cp -T "$first" "$bgd"
else
cp -T "$first" "$bgl"
fi
reload mode/swww_single
util_write_config "chore.bg_$mode" "$first"
reload mode/swww_single "$mode"