aboutsummaryrefslogtreecommitdiff
path: root/home/dot_local/share/mode
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2026-08-02 14:48:29 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2026-08-02 14:48:29 +0200
commite43eb1177872f52e949fb5f0f93396ed94b0d093 (patch)
tree78b73af6a989fa2996d71b112e161b70d35081ef /home/dot_local/share/mode
parent2f14a896e4b897bd747c24d7ad8e9e7bb3237d03 (diff)
move to chezmoi
Diffstat (limited to 'home/dot_local/share/mode')
-rw-r--r--home/dot_local/share/mode/executable_mode148
-rw-r--r--home/dot_local/share/mode/plug.d/10_lib46
-rw-r--r--home/dot_local/share/mode/plug.d/20_export_colors17
-rw-r--r--home/dot_local/share/mode/plug.d/20_export_mode9
-rw-r--r--home/dot_local/share/mode/plug.d/20_export_vim_theme6
-rw-r--r--home/dot_local/share/mode/plug.d/50_accent15
-rw-r--r--home/dot_local/share/mode/reload.d/brave80
-rw-r--r--home/dot_local/share/mode/reload.d/executable_dunst3
-rw-r--r--home/dot_local/share/mode/reload.d/executable_fcitx53
-rw-r--r--home/dot_local/share/mode/reload.d/executable_i32
-rw-r--r--home/dot_local/share/mode/reload.d/executable_nvim6
-rw-r--r--home/dot_local/share/mode/reload.d/executable_polybar3
-rw-r--r--home/dot_local/share/mode/reload.d/executable_term30
-rw-r--r--home/dot_local/share/mode/reload.d/gtk8
-rw-r--r--home/dot_local/share/mode/switch.d/executable_anki120
-rw-r--r--home/dot_local/share/mode/switch.d/executable_chromium48
-rw-r--r--home/dot_local/share/mode/switch.d/executable_discord34
-rw-r--r--home/dot_local/share/mode/switch.d/executable_dunst24
-rw-r--r--home/dot_local/share/mode/switch.d/executable_fcitx567
-rw-r--r--home/dot_local/share/mode/switch.d/executable_gtk11
-rw-r--r--home/dot_local/share/mode/switch.d/executable_i314
-rw-r--r--home/dot_local/share/mode/switch.d/executable_kitty27
-rw-r--r--home/dot_local/share/mode/switch.d/executable_mode10
-rw-r--r--home/dot_local/share/mode/switch.d/executable_polybar16
-rw-r--r--home/dot_local/share/mode/switch.d/executable_vim59
-rw-r--r--home/dot_local/share/mode/switch.d/executable_wall2
-rw-r--r--home/dot_local/share/mode/switch.d/executable_xrdb22
-rw-r--r--home/dot_local/share/mode/switch.d/executable_zathura27
-rw-r--r--home/dot_local/share/mode/themes/github-black25
-rw-r--r--home/dot_local/share/mode/themes/github-dark25
-rw-r--r--home/dot_local/share/mode/themes/github-light25
-rw-r--r--home/dot_local/share/mode/themes/rose-pine-dawn28
-rw-r--r--home/dot_local/share/mode/themes/symlink_dark1
-rw-r--r--home/dot_local/share/mode/themes/symlink_light1
-rw-r--r--home/dot_local/share/mode/themes/xcode-dark24
35 files changed, 986 insertions, 0 deletions
diff --git a/home/dot_local/share/mode/executable_mode b/home/dot_local/share/mode/executable_mode
new file mode 100644
index 0000000..dc188e9
--- /dev/null
+++ b/home/dot_local/share/mode/executable_mode
@@ -0,0 +1,148 @@
+#!/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
+
diff --git a/home/dot_local/share/mode/plug.d/10_lib b/home/dot_local/share/mode/plug.d/10_lib
new file mode 100644
index 0000000..b3a0276
--- /dev/null
+++ b/home/dot_local/share/mode/plug.d/10_lib
@@ -0,0 +1,46 @@
+#!/bin/sh
+# utility library functions
+hex_to_rgb_array() { pastel format rgb "$1" | cut -c4- | tr '()' '[]' ; }
+
+mix_rgb() { pastel mix --colorspace=RGB --fraction="$3" "$1" "$2" | pastel format hex ; }
+
+getvar() {
+ key="$1"
+ eval "printf '%s' \"\$$key\""
+}
+
+setvar() {
+ key="$1"
+ value="$2"
+ eval "$key='$(printf '%s' "$value")'"
+}
+
+themevar() {
+ key="$1"
+ if [ $# -eq 1 ] ; then
+ value="$(getvar "$key")"
+ else
+ value="$2"
+ setvar "$key" "$value"
+ fi
+
+ vars="$vars
+$(printf "export %s='%s'" "$key" "$value")"
+ eval "export $key"
+}
+
+mkcd() {
+ mkdir -p "$1"
+ cd "$1"
+}
+
+respawn_daemon() {
+ killall -q "$1" && fork "$@"
+}
+
+silent_fail_if_no_commmand() {
+ for name in "$@" ; do
+ [ -z "$(command -v "$name")" ] && exit
+ done
+}
+
diff --git a/home/dot_local/share/mode/plug.d/20_export_colors b/home/dot_local/share/mode/plug.d/20_export_colors
new file mode 100644
index 0000000..0f53d1f
--- /dev/null
+++ b/home/dot_local/share/mode/plug.d/20_export_colors
@@ -0,0 +1,17 @@
+#!/bin/sh
+# colors must be #RRGGBB
+check_color() {
+ (
+ eval "color=\"\${$1}\""
+ exit "$(echo "$color" | sed -n '/^#[0-9a-fA-F]\{6\}$/p' | wc -l)"
+ )
+ if [ $? -ne 1 ] ; then
+ echo "error: color $1 is not properly formatted (#RRGGBB)"
+ stupid && exit 1
+ fi
+ themevar "$1"
+}
+for color in $(seq 0 15 | sed 's/^/color/') bg fg ; do
+ check_color $color
+done
+
diff --git a/home/dot_local/share/mode/plug.d/20_export_mode b/home/dot_local/share/mode/plug.d/20_export_mode
new file mode 100644
index 0000000..c82c4e1
--- /dev/null
+++ b/home/dot_local/share/mode/plug.d/20_export_mode
@@ -0,0 +1,9 @@
+#!/bin/sh
+# $mode = "light" | "dark"
+if [ "$mode" != 'dark' ] && [ "$mode" != 'light' ] ; then
+ pastel format hsl-lightness "$bg" | awk '{ exit($1 > 0.5) }'
+ [ $? -eq 0 ] && mode=dark || mode=light
+ echo "warn: theme $theme did not define \$mode as \"light\" or \"dark\", guessed $mode" >&2
+fi
+themevar mode
+
diff --git a/home/dot_local/share/mode/plug.d/20_export_vim_theme b/home/dot_local/share/mode/plug.d/20_export_vim_theme
new file mode 100644
index 0000000..12304f3
--- /dev/null
+++ b/home/dot_local/share/mode/plug.d/20_export_vim_theme
@@ -0,0 +1,6 @@
+#!/bin/sh
+# warn if the vim theme is not installed
+if [ "$(find "$XDG_CONFIG_HOME/nvim" -name "$vim_theme_name.vim" | wc -l)" -eq 0 ] ; then
+ echo "warn: vim theme $vim_theme_name does not appear to be installed" >&2
+fi
+themevar vim_theme_name
diff --git a/home/dot_local/share/mode/plug.d/50_accent b/home/dot_local/share/mode/plug.d/50_accent
new file mode 100644
index 0000000..ceb3209
--- /dev/null
+++ b/home/dot_local/share/mode/plug.d/50_accent
@@ -0,0 +1,15 @@
+#!/bin/sh
+# create accent color differently for dark/light mode
+
+# do not generate accent color if already explicitly defined by theme
+[ -n "$accent" ] && return
+
+if [ "$mode" = "light" ] ; then
+ themevar accent "$color15"
+ themevar accent_text "$color0"
+fi
+if [ "$mode" = "dark" ] ; then
+ themevar accent "$(mix_rgb $bg $color0 0.5)"
+ themevar accent_text "$fg"
+fi
+
diff --git a/home/dot_local/share/mode/reload.d/brave b/home/dot_local/share/mode/reload.d/brave
new file mode 100644
index 0000000..6f6caeb
--- /dev/null
+++ b/home/dot_local/share/mode/reload.d/brave
@@ -0,0 +1,80 @@
+#!/bin/sh
+# WIP
+browser='brave'
+driver='chromedriver'
+devtools_addr='localhost:9222'
+url_base='http://localhost:9515'
+
+command -v "$browser" > /dev/null && command -v "$driver" > /dev/null
+[ $? -ne 0 ] && exit 0
+
+get() { curl -s -o - -X GET "$@" ; }
+post() { curl -s -o - -X POST -H 'Content-Type: application/json' -d @- "$@" ; }
+delete() { curl -s -X DELETE "$@" > /dev/null ; }
+
+$driver --silent > /dev/null &
+sleep 0.1 # (wait for chromedriver to start server)
+
+create_session() {
+ args="$(jq --raw-input --slurp 'split("\n") | map(select(. != ""))' << EOF
+new-window
+headless=new
+EOF
+ )"
+ jq -nc \
+ --arg name "$browser" \
+ --arg debugger "$devtools_addr" \
+ --argjson args "$args" \
+ '{
+ desiredCapabilities: {
+ "browserName": $name,
+ "goog:chromeOptions": {
+ binary: $name,
+ args: $args,
+ debuggerAddress: $debugger
+ },
+ }
+ }' |\
+ post "$url_base/session" |\
+ jq --raw-output '.sessionId'
+}
+
+navigate() {
+ jq -nc --arg url "$1" '{"url": $url}' |\
+ post "$url_base/url" > /dev/null
+}
+
+script() {
+ jq -nc --arg script "$1" '{"script": $script, args: []}' |\
+ post "$url_base/execute/sync" > /dev/null
+}
+
+create_tab() {
+ handle="$(jq -nc '{"type": "tab"}' |\
+ post "$url_base/window/new" |\
+ jq --raw-output '.value.handle')"
+ jq -nc --arg handle "$handle" '{"name": $handle}' |\
+ post "$url_base/window" > /dev/null
+}
+
+# create session
+session_id="$(create_session)"
+url_base="$url_base/session/$session_id"
+create_tab
+
+# set chrome theme
+navigate 'brave://settings'
+script "chrome.send(\"setBraveThemeType\", [$([ "$mode" = "light" ] && echo "2" || echo "1")])"
+
+# todo: reload theme extension
+# navigate 'brave://extensions'
+# - run `chrome.developerPrivate.loadUnpacked()` (TODO: how to handle inputting file path non-interactively)
+# TODO: how to use chromedriver from script (preferably without nodejs+npm or python3+pip dependencies?)
+
+# cleanup
+delete "$url_base/window"
+delete "$url_base"
+kill $(jobs -p)
+wait $(jobs -p)
+
+# reference: https://w3c.github.io/webdriver/
diff --git a/home/dot_local/share/mode/reload.d/executable_dunst b/home/dot_local/share/mode/reload.d/executable_dunst
new file mode 100644
index 0000000..430320c
--- /dev/null
+++ b/home/dot_local/share/mode/reload.d/executable_dunst
@@ -0,0 +1,3 @@
+#!/bin/sh
+respawn_daemon dunst
+
diff --git a/home/dot_local/share/mode/reload.d/executable_fcitx5 b/home/dot_local/share/mode/reload.d/executable_fcitx5
new file mode 100644
index 0000000..cd27698
--- /dev/null
+++ b/home/dot_local/share/mode/reload.d/executable_fcitx5
@@ -0,0 +1,3 @@
+#!/bin/sh
+fork fcitx5 -rd
+
diff --git a/home/dot_local/share/mode/reload.d/executable_i3 b/home/dot_local/share/mode/reload.d/executable_i3
new file mode 100644
index 0000000..96212cf
--- /dev/null
+++ b/home/dot_local/share/mode/reload.d/executable_i3
@@ -0,0 +1,2 @@
+#!/bin/sh
+fork i3-msg reload
diff --git a/home/dot_local/share/mode/reload.d/executable_nvim b/home/dot_local/share/mode/reload.d/executable_nvim
new file mode 100644
index 0000000..cfabcc7
--- /dev/null
+++ b/home/dot_local/share/mode/reload.d/executable_nvim
@@ -0,0 +1,6 @@
+#!/bin/sh
+silent_fail_if_no_commmand nvr
+nvr --serverlist | while read -r nvim_socket ; do
+ fork nvr --nostart --servername "$nvim_socket" -c 'source $XDG_CONFIG_HOME/nvim/mode.vim'
+done
+
diff --git a/home/dot_local/share/mode/reload.d/executable_polybar b/home/dot_local/share/mode/reload.d/executable_polybar
new file mode 100644
index 0000000..1976811
--- /dev/null
+++ b/home/dot_local/share/mode/reload.d/executable_polybar
@@ -0,0 +1,3 @@
+#!/bin/sh
+fork polybar-msg cmd restart
+
diff --git a/home/dot_local/share/mode/reload.d/executable_term b/home/dot_local/share/mode/reload.d/executable_term
new file mode 100644
index 0000000..b711d56
--- /dev/null
+++ b/home/dot_local/share/mode/reload.d/executable_term
@@ -0,0 +1,30 @@
+#!/bin/sh
+escape_msgs="$(cat << EOF | tr -d '\n'
+\033]11;$bg\007
+\033]10;$fg\007
+\033]12;$fg\007
+\033]14;$bg\007
+\033]13;$fg\007
+\033]17;$color8\007
+\033]708;$bg\007
+\033]4;0;$color0\007
+\033]4;1;$color1\007
+\033]4;2;$color2\007
+\033]4;3;$color3\007
+\033]4;4;$color4\007
+\033]4;5;$color5\007
+\033]4;6;$color6\007
+\033]4;7;$color7\007
+\033]4;8;$color8\007
+\033]4;9;$color9\007
+\033]4;10;$color10\007
+\033]4;11;$color11\007
+\033]4;12;$color12\007
+\033]4;13;$color13\007
+\033]4;14;$color14\007
+\033]4;15;$color15\007
+EOF
+)"
+
+find /dev/pts -exec sh -c "printf '$escape_msgs' > {}" \; 2> /dev/null
+
diff --git a/home/dot_local/share/mode/reload.d/gtk b/home/dot_local/share/mode/reload.d/gtk
new file mode 100644
index 0000000..767969d
--- /dev/null
+++ b/home/dot_local/share/mode/reload.d/gtk
@@ -0,0 +1,8 @@
+#!/bin/sh
+# this is max jank but xfsettingsd does other things besides live gtk theme
+# reloading, and i don't like having it running constantly because it fucks
+# up fcitx5 and xbindkeys
+fork xfsettingsd --replace
+sleep 1
+killall -q xfsettingsd
+
diff --git a/home/dot_local/share/mode/switch.d/executable_anki b/home/dot_local/share/mode/switch.d/executable_anki
new file mode 100644
index 0000000..7572b00
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_anki
@@ -0,0 +1,120 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+# this generates theme files compatible with Anki-redesign:
+# <https://ankiweb.net/shared/info/308574457>
+# <https://github.com/shirajuki/anki-redesign>
+ANKI_REDESIGN="$XDG_DATA_HOME/Anki2/addons21/308574457"
+
+# ensure folders exist
+mkdir -p "$ANKI_REDESIGN/user_files/themes"
+
+# ensure theme is set to mode
+CONFIG="$ANKI_REDESIGN/config.json"
+[ -e "$CONFIG" ] && jq '.theme = "mode"' "$CONFIG" | sponge "$CONFIG"
+
+name() {
+ key="$1"
+ value="$2"
+ key_json="$(printf '%s' "$key" | tr '[:lower:]' '[:upper:]' | tr -c '[:alnum:]' '_')"
+ key_css="--$(printf '%s' "$key" | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]' '-')"
+ echo "\"$key_json\": [ \"\", \"\", \"$value\", \"$value\", \"$key_css\" ]"
+}
+
+unused="#ff00ff"
+surface_0=$(mix_rgb $bg '#000000' 0.7)
+surface_1=$(mix_rgb $color0 $bg 0.40)
+surface_2=$(mix_rgb $color0 $bg 0.60)
+
+cat << EOF > "$ANKI_REDESIGN/user_files/themes/mode.json"
+{
+ "colors": {
+ $(name accent-card "$color4"),
+ $(name accent-danger "$color1"),
+ $(name accent-note "$color2"),
+ $(name border "$bg"),
+ $(name border-focus "#3b82f6"),
+ $(name border-strong "#020202"),
+ $(name border-subtle "$bg"),
+ $(name buried-fg "#777733"),
+ $(name button-bg "$surface_1"),
+ $(name button-disabled "$bg"),
+ $(name button-focus-bg "#0093d0"),
+ $(name button-gradient-end "$surface_2"),
+ $(name button-gradient-start "$surface_2"),
+ $(name button-hover-border "$accent"),
+ $(name button-primary-bg "$accent"),
+ $(name button-primary-disabled "#4484ed"),
+ $(name button-primary-gradient-end "$accent"),
+ $(name button-primary-gradient-start "$accent"),
+ $(name canvas "$bg"),
+ $(name canvas-code "$surface_0"),
+ $(name canvas-elevated "$bg"),
+ $(name canvas-inset "$surface_1"),
+ $(name canvas-overlay "$bg"),
+ $(name current-deck "$unused"),
+ $(name disabled "#777"),
+ $(name faint-border "#29292b"),
+ $(name fg "$fg"),
+ $(name fg-disabled "#737373"),
+ $(name fg-faint "$color0"),
+ $(name fg-link "#bfdbfe"),
+ $(name fg-subtle "#858585"),
+ $(name flag1-bg "#aa5555"),
+ $(name flag1-fg "#ff7b7b"),
+ $(name flag2-bg "#ac653a"),
+ $(name flag2-fg "#f5aa41"),
+ $(name flag3-bg "#559238"),
+ $(name flag3-fg "#86ce5d"),
+ $(name flag4-bg "#506aa3"),
+ $(name flag4-fg "#6f9dff"),
+ $(name flag5-bg "#975d8f"),
+ $(name flag5-fg "#f097e4"),
+ $(name flag6-bg "#399185"),
+ $(name flag6-fg "#5ccfca"),
+ $(name flag7-bg "#624b77"),
+ $(name flag7-fg "#9f63d3"),
+ $(name flag-1 "$color9"),
+ $(name flag-2 "$color11"),
+ $(name flag-3 "$color10"),
+ $(name flag-4 "$color12"),
+ $(name flag-5 "$color13"),
+ $(name flag-6 "$color14"),
+ $(name flag-7 "$color5"),
+ $(name focus-shadow "#0093d0"),
+ $(name frame-bg "$surface_1"),
+ $(name highlight-bg "$accent"),
+ $(name highlight-fg "$accent_text"),
+ $(name learn-count "#ff935b"),
+ $(name link "#77ccff"),
+ $(name marked-bg "#77c"),
+ $(name medium-border "#444"),
+ $(name new-count "#77ccff"),
+ $(name review-count "#5ccc00"),
+ $(name scrollbar-bg "$surface_1"),
+ $(name scrollbar-bg-active "$surface_2"),
+ $(name scrollbar-bg-hover "$surface_2"),
+ $(name selected-bg "rgba(147, 197, 253, 0.5)"),
+ $(name selected-fg "$fg"),
+ $(name shadow "#141414"),
+ $(name shadow-focus "#6366f1"),
+ $(name shadow-inset "#202020"),
+ $(name shadow-subtle "#363636"),
+ $(name slightly-grey-text "#ccc"),
+ $(name state-buried "#92400e"),
+ $(name state-learn "$color1"),
+ $(name state-marked "#a855f7"),
+ $(name state-new "$color4"),
+ $(name state-review "$color2"),
+ $(name state-suspended "#fef9c3"),
+ $(name suspended-bg "#aaaa33"),
+ $(name suspended-fg "#ffffb2"),
+ $(name text-fg "$fg"),
+ $(name tooltip-bg "$surface_1"),
+ $(name window-bg "$bg"),
+ $(name zero-count "#444")
+ },
+ "version": { "major": -1, "minor": -1 }
+}
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_chromium b/home/dot_local/share/mode/switch.d/executable_chromium
new file mode 100644
index 0000000..0ea2caa
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_chromium
@@ -0,0 +1,48 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+mkcd "$XDG_CACHE_HOME/mode/chromium"
+
+rm -f 'Cached Theme.pak'
+
+magick -size 100x100 "xc:$bg" 'bg.png'
+bg_alt=$(mix_rgb $bg $color0 0.65)
+fg_alt=$(mix_rgb $fg $color15 0.35)
+
+bg="$(hex_to_rgb_array "$bg")"
+fg="$(hex_to_rgb_array "$fg")"
+bg_alt="$(hex_to_rgb_array "$bg_alt")"
+fg_alt="$(hex_to_rgb_array "$fg_alt")"
+
+cat << EOF > 'manifest.json'
+{
+ "description": "colorscheme generated by mode",
+ "manifest_version": 2,
+ "name": "mode theme",
+ "theme": {
+ "images": { "theme_frame": "bg.png" },
+ "colors": {
+ "frame": $bg_alt,
+ "button_background": $fg,
+ "ntp_background": $bg,
+ "ntp_text": $bg_alt,
+ "toolbar": $bg,
+ "toolbar_button_icon": $fg,
+ "tab_background_text": $fg_alt,
+ "tab_background_text_inactive": $fg_alt,
+ "tab_background_text_incognito": $fg_alt,
+ "tab_background_text_incognito_inactive": $fg_alt,
+ "bookmark_text": $fg,
+ "tab_text": $fg
+ },
+ "tints": {
+ "buttons": [ -1, -1, -1 ],
+ "frame_inactive": [ -1, -1, -1 ],
+ "frame_incognito": [ -1, -1, -1 ],
+ "frame_incognito_inactive": [ -1, -1, -1 ]
+ }
+ },
+ "version": "2"
+}
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_discord b/home/dot_local/share/mode/switch.d/executable_discord
new file mode 100644
index 0000000..dd7e5e3
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_discord
@@ -0,0 +1,34 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+mkcd "$XDG_CONFIG_HOME/BetterDiscord/themes"
+cat << EOF > 'mode.theme.css'
+/**
+ * @name mode
+ * @author mode
+ * @version 0
+*/
+
+/* AUTOMATICALLY GENERATED, DO NOT EDIT */
+
+.theme-dark, .theme-light {
+ --background-primary: $bg;
+ --background-secondary: $bg;
+ --background-secondary-alt: $bg;
+ --text-primary: $fg;
+ --text-secondary: $color15;
+ --accent: $color4;
+ --accent-alt: $color12;
+ --error: $color1;
+ --error-alt: $color9;
+}
+
+.theme-dark {
+ --background-tertiary: $(mix_rgb $bg '#000000' 0.7);
+}
+
+.theme-light {
+ --background-tertiary: $bg;
+}
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_dunst b/home/dot_local/share/mode/switch.d/executable_dunst
new file mode 100644
index 0000000..d7d9a2b
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_dunst
@@ -0,0 +1,24 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+mkcd "$XDG_CONFIG_HOME/dunst"
+cat 'base' - << EOF > 'dunstrc'
+frame_color = "$accent"
+
+[urgency_low]
+background = "$bg"
+foreground = "$fg"
+timeout = 10
+
+[urgency_normal]
+background = "$bg"
+foreground = "$fg"
+timeout = 10
+
+[urgency_critical]
+background = "$color1"
+foreground = "$bg"
+frame_color = "$color1"
+timeout = 0
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_fcitx5 b/home/dot_local/share/mode/switch.d/executable_fcitx5
new file mode 100644
index 0000000..2cc6ccb
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_fcitx5
@@ -0,0 +1,67 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+mkcd "$XDG_DATA_HOME/fcitx5/themes/mode"
+rounding=6
+size=$(( 2 * $rounding + 4 ))
+margin_h=6
+margin_v=4
+
+bg='#000000'
+fg='#ffffff'
+accent='#404040'
+accent_text=$fg
+sel_bg=$(mix_rgb $color12 $bg 0.4)
+sel_fg=$fg
+
+magick \
+ -size ${size}x${size} xc:transparent \
+ -fill xc:"$accent" \
+ -draw "roundrectangle 0,0 $(( $size - 1 )),$(( $size - 1 )) $rounding,$rounding" \
+ highlight.png
+
+cat base.conf - << EOF > theme.conf
+[InputPanel]
+NormalColor=$fg
+HighlightCandidateColor=$accent_text
+HighlightColor=$sel_fg
+HighlightBackgroundColor=$sel_bg
+
+[InputPanel/Background]
+Color=$bg
+
+[InputPanel/Highlight]
+Image=highlight.png
+
+[InputPanel/Highlight/Margin]
+Left=$rounding
+Right=$rounding
+Top=$rounding
+Bottom=$rounding
+
+[InputPanel/ContentMargin]
+Left=$(( 2 + $rounding - $margin_h ))
+Right=$(( 2 + $rounding - $margin_h ))
+Top=$(( 2 + $rounding - $margin_v ))
+Bottom=$(( 2 + $rounding - $margin_v ))
+
+[InputPanel/TextMargin]
+Left=$margin_h
+Right=$margin_h
+Top=$margin_v
+Bottom=$margin_v
+
+[Menu]
+NormalColor=$fg
+
+[Menu/Background]
+Color=$bg
+
+[Menu/Highlight]
+Color=$accent
+
+[Menu/Separator]
+Color=$color7
+
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_gtk b/home/dot_local/share/mode/switch.d/executable_gtk
new file mode 100644
index 0000000..95d3e53
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_gtk
@@ -0,0 +1,11 @@
+#!/bin/sh
+GTK_3_SETTINGS_INI="$XDG_CONFIG_HOME/gtk-3.0/settings.ini"
+if [ "$mode" = "light" ]; then
+ sed -e 's/-Dark/-Light/' -e 's/-dark/-light/' -i "$GTK_3_SETTINGS_INI"
+ sed "s/gtk-application-prefer-dark-theme.*/gtk-application-prefer-dark-theme=false/" -i "$GTK_3_SETTINGS_INI"
+else
+ sed -e 's/-Dark/-Light/' -e 's/-dark/-light/' -i "$GTK_3_SETTINGS_INI"
+ sed "s/gtk-application-prefer-dark-theme.*/gtk-application-prefer-dark-theme=true/" -i "$GTK_3_SETTINGS_INI"
+fi
+grep gtk-theme-name "$GTK_3_SETTINGS_INI" | cut -f2 -d= | xargs xfconf-query -c xsettings -p /Net/ThemeName -s
+
diff --git a/home/dot_local/share/mode/switch.d/executable_i3 b/home/dot_local/share/mode/switch.d/executable_i3
new file mode 100644
index 0000000..713869e
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_i3
@@ -0,0 +1,14 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+indicator="$color0"
+mkcd "$XDG_CONFIG_HOME/i3"
+cat << EOF > 'color.conf'
+client.focused $fg $bg $fg $indicator $bg
+client.focused_inactive $bg $bg $fg $indicator $bg
+client.unfocused $bg $bg $fg $indicator $bg
+client.urgent $bg $bg $fg $indicator $bg
+client.placeholder $bg $bg $fg $indicator $bg
+client.background $bg
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_kitty b/home/dot_local/share/mode/switch.d/executable_kitty
new file mode 100644
index 0000000..eeb81d0
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_kitty
@@ -0,0 +1,27 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+mkcd "$XDG_CONFIG_HOME/kitty"
+
+cat << EOF > 'color.conf'
+background $bg
+foreground $fg
+
+color0 $color0
+color1 $color1
+color2 $color2
+color3 $color3
+color4 $color4
+color5 $color5
+color6 $color6
+color7 $color7
+color8 $color8
+color9 $color9
+color10 $color10
+color11 $color11
+color12 $color12
+color13 $color13
+color14 $color14
+color15 $color15
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_mode b/home/dot_local/share/mode/switch.d/executable_mode
new file mode 100644
index 0000000..8866486
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_mode
@@ -0,0 +1,10 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+mkcd "$XDG_CACHE_HOME/mode/state"
+
+echo "$mode" > mode
+rm theme
+ln -sf "$theme" theme
+echo "#!/bin/sh$vars" > vars
+
diff --git a/home/dot_local/share/mode/switch.d/executable_polybar b/home/dot_local/share/mode/switch.d/executable_polybar
new file mode 100644
index 0000000..7087735
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_polybar
@@ -0,0 +1,16 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+mkcd "$XDG_CONFIG_HOME/polybar"
+cat << EOF > 'colors.ini'
+[color]
+bg = \${xrdb:background:$bg}
+fg = \${xrdb:foreground:$fg}
+fg-alt = \${xrdb:background:$bg}
+fg-half = \${xrdb:color8:$color8}
+
+alpha = #00000000
+
+; vim:ft=dosini
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_vim b/home/dot_local/share/mode/switch.d/executable_vim
new file mode 100644
index 0000000..2220b1a
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_vim
@@ -0,0 +1,59 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+mkcd "$XDG_CONFIG_HOME/nvim/mode"
+
+# lightline
+cat << EOF > 'lightline.vim'
+let s:bg = [ '$bg', 'NONE' ]
+let s:fg = [ '$fg', 'NONE' ]
+let s:mode = [ '$color0', 'NONE' ]
+let s:faint = [ '$color8', 'NONE' ]
+let s:none = [ 'NONE', 'NONE' ]
+let s:test = [ '#ff00ff', 'NONE' ]
+
+let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
+let s:p.normal.left = [ [ s:fg, s:mode ], [ s:faint, s:bg ] ]
+let s:p.normal.right = [ [ s:faint, s:bg ] ]
+let s:p.normal.middle = [ [ s:bg, s:bg ] ]
+let s:p.normal.error = [ [ s:test, s:test ] ]
+let s:p.normal.warning = [ [ s:test, s:test ] ]
+let s:p.inactive.left = copy(s:p.normal.left)
+let s:p.inactive.right = copy(s:p.normal.right)
+let s:p.inactive.middle = copy(s:p.normal.middle)
+let s:p.insert.left = copy(s:p.normal.left)
+let s:p.replace.left = copy(s:p.insert.left)
+let s:p.visual.left = copy(s:p.insert.left)
+let s:p.tabline.left = copy(s:p.normal.right)
+let s:p.tabline.tabsel = [ [ s:fg, s:mode ] ]
+let s:p.tabline.middle = copy(s:p.normal.right)
+let s:p.tabline.right = copy(s:p.normal.right)
+
+let g:lightline#colorscheme#auto#palette = lightline#colorscheme#flatten(s:p)
+EOF
+
+# terminal colors
+cat << EOF > 'termcolors.vim'
+let g:terminal_color_0 = '$color0'
+let g:terminal_color_1 = '$color1'
+let g:terminal_color_2 = '$color2'
+let g:terminal_color_3 = '$color3'
+let g:terminal_color_4 = '$color4'
+let g:terminal_color_5 = '$color5'
+let g:terminal_color_6 = '$color6'
+let g:terminal_color_7 = '$color7'
+let g:terminal_color_8 = '$color8'
+let g:terminal_color_9 = '$color9'
+let g:terminal_color_10 = '$color10'
+let g:terminal_color_11 = '$color11'
+let g:terminal_color_12 = '$color12'
+let g:terminal_color_13 = '$color13'
+let g:terminal_color_14 = '$color14'
+let g:terminal_color_15 = '$color15'
+EOF
+
+# color scheme
+cat << EOF > 'colorscheme.vim'
+colorscheme $vim_theme_name
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_wall b/home/dot_local/share/mode/switch.d/executable_wall
new file mode 100644
index 0000000..c5ced92
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_wall
@@ -0,0 +1,2 @@
+#!/bin/sh
+bgcol "$bg"
diff --git a/home/dot_local/share/mode/switch.d/executable_xrdb b/home/dot_local/share/mode/switch.d/executable_xrdb
new file mode 100644
index 0000000..591a530
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_xrdb
@@ -0,0 +1,22 @@
+#!/bin/sh
+cat << EOF | xrdb -override
+*.color0: $color0
+*.color1: $color1
+*.color2: $color2
+*.color3: $color3
+*.color4: $color4
+*.color5: $color5
+*.color6: $color6
+*.color7: $color7
+*.color8: $color8
+*.color9: $color9
+*.color10: $color10
+*.color11: $color11
+*.color12: $color12
+*.color13: $color13
+*.color14: $color14
+*.color15: $color15
+*.foreground: $fg
+*.background: $bg
+EOF
+
diff --git a/home/dot_local/share/mode/switch.d/executable_zathura b/home/dot_local/share/mode/switch.d/executable_zathura
new file mode 100644
index 0000000..8d7e311
--- /dev/null
+++ b/home/dot_local/share/mode/switch.d/executable_zathura
@@ -0,0 +1,27 @@
+#!/bin/sh
+[ $no_cfg -eq 1 ] && return
+
+mkcd "$XDG_CONFIG_HOME/zathura"
+cat << EOF > 'colors'
+set completion-bg "$bg"
+set completion-fg "$fg"
+set completion-highlight-bg "$accent"
+set completion-highlight-fg "$accent_text"
+set default-bg "$bg"
+set default-fg "$fg"
+set highlight-active-color "$(echo "$accent" | pastel set alpha 0.5 | pastel format rgb)"
+set highlight-color "$(echo "$accent_text" | pastel set alpha 0.5 | pastel format rgb)"
+set inputbar-bg "$bg"
+set inputbar-fg "$fg"
+set notification-bg "$bg"
+set notification-error-bg "$color9"
+set notification-error-fg "$bg"
+set notification-fg "$fg"
+set notification-warning-bg "$color9"
+set notification-warning-fg "$bg"
+set recolor-darkcolor "$fg"
+set recolor-lightcolor "$bg"
+set statusbar-bg "$bg"
+set statusbar-fg "$fg"
+EOF
+
diff --git a/home/dot_local/share/mode/themes/github-black b/home/dot_local/share/mode/themes/github-black
new file mode 100644
index 0000000..34b507c
--- /dev/null
+++ b/home/dot_local/share/mode/themes/github-black
@@ -0,0 +1,25 @@
+#!/bin/sh
+mode=dark
+
+color0='#484f58'
+color1='#ffa198'
+color2='#56d364'
+color3='#e3b341'
+color4='#79c0ff'
+color5='#d2a8ff'
+color6='#56d4dd'
+color7='#b1bac4'
+color8='#6e7681'
+color9='#ff7b72'
+color10='#3fb950'
+color11='#d29922'
+color12='#58a6ff'
+color13='#bc8cff'
+color14='#39c5cf'
+color15='#ffffff'
+
+bg='#000000'
+fg='#e6edf3'
+
+vim_theme_name='ghdark'
+
diff --git a/home/dot_local/share/mode/themes/github-dark b/home/dot_local/share/mode/themes/github-dark
new file mode 100644
index 0000000..577106c
--- /dev/null
+++ b/home/dot_local/share/mode/themes/github-dark
@@ -0,0 +1,25 @@
+#!/bin/sh
+mode=dark
+
+color0='#484f58'
+color1='#ffa198'
+color2='#56d364'
+color3='#e3b341'
+color4='#79c0ff'
+color5='#d2a8ff'
+color6='#56d4dd'
+color7='#b1bac4'
+color8='#6e7681'
+color9='#ff7b72'
+color10='#3fb950'
+color11='#d29922'
+color12='#58a6ff'
+color13='#bc8cff'
+color14='#39c5cf'
+color15='#ffffff'
+
+bg='#0d1117'
+fg='#e6edf3'
+
+vim_theme_name='ghdark'
+
diff --git a/home/dot_local/share/mode/themes/github-light b/home/dot_local/share/mode/themes/github-light
new file mode 100644
index 0000000..d0162f8
--- /dev/null
+++ b/home/dot_local/share/mode/themes/github-light
@@ -0,0 +1,25 @@
+#!/bin/sh
+mode=light
+
+color0='#d1d5da'
+color1='#cb2431'
+color2='#22863a'
+color3='#b08800'
+color4='#005cc5'
+color5='#5a32a3'
+color6='#3192aa'
+color7='#6a737d'
+color8='#959da5'
+color9='#d73a49'
+color10='#28a745'
+color11='#dbab09'
+color12='#0366d6'
+color13='#5a32a3'
+color14='#1b7c83'
+color15='#24292e'
+
+bg='#ffffff'
+fg='#24292e'
+
+vim_theme_name='github-light'
+
diff --git a/home/dot_local/share/mode/themes/rose-pine-dawn b/home/dot_local/share/mode/themes/rose-pine-dawn
new file mode 100644
index 0000000..dfed420
--- /dev/null
+++ b/home/dot_local/share/mode/themes/rose-pine-dawn
@@ -0,0 +1,28 @@
+#!/bin/sh
+mode=light
+
+color0='#c4bdc3'
+color1='#b4637a'
+color2='#286983'
+color3='#ea9d34'
+color4='#56949f'
+color5='#907aa9'
+color6='#d7827e'
+color7='#575279'
+color8='#797593'
+color9='#b4637a'
+color10='#286983'
+color11='#ea9d34'
+color12='#56949f'
+color13='#907aa9'
+color14='#d7827e'
+color15='#575279'
+
+bg='#faf4ed'
+fg='#575279'
+
+accent='#d7827e'
+accent_text='#f4ede8'
+
+vim_theme_name='rose-pine-dawn'
+
diff --git a/home/dot_local/share/mode/themes/symlink_dark b/home/dot_local/share/mode/themes/symlink_dark
new file mode 100644
index 0000000..b5d11f8
--- /dev/null
+++ b/home/dot_local/share/mode/themes/symlink_dark
@@ -0,0 +1 @@
+github-dark
diff --git a/home/dot_local/share/mode/themes/symlink_light b/home/dot_local/share/mode/themes/symlink_light
new file mode 100644
index 0000000..2c27e1d
--- /dev/null
+++ b/home/dot_local/share/mode/themes/symlink_light
@@ -0,0 +1 @@
+github-light
diff --git a/home/dot_local/share/mode/themes/xcode-dark b/home/dot_local/share/mode/themes/xcode-dark
new file mode 100644
index 0000000..eb75b80
--- /dev/null
+++ b/home/dot_local/share/mode/themes/xcode-dark
@@ -0,0 +1,24 @@
+#!/bin/sh
+mode=dark
+
+color0='#43454b'
+color1='#ff8a7a'
+color2='#83c9bc'
+color3='#d9c668'
+color4='#4ec4e6'
+color5='#ff85b8'
+color6='#cda1ff'
+color7='#ffffff'
+color8='#838991'
+color9='#ff8a7a'
+color10='#b1faeb'
+color11='#ffa14f'
+color12='#6bdfff'
+color13='#ff85b8'
+color14='#e5cfff'
+color15='#ffffff'
+
+bg='#1f1f24'
+fg='#e6edf3'
+
+vim_theme_name='xcodedarkhc'