colorscheme fixes & new implementations
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
-- lua implementation of the dotwryn colorscheme library (scwrypts/dotwryn/desktop/colorscheme)
|
||||
--
|
||||
-- usage:
|
||||
-- local colorscheme = dofile(os.getenv("DOTWRYN") .. "/scwrypts/dotwryn/desktop/colorscheme/colorscheme.lua")
|
||||
-- local theme = colorscheme.load() -- the active theme
|
||||
-- local theme = colorscheme.load("winter") -- a named theme
|
||||
--
|
||||
-- theme.name -- e.g. "halloween"
|
||||
-- theme.values -- the merged (default.yaml + theme) source, references unresolved
|
||||
-- theme.get_hex(".i3.focused.border", ".material.secondary.500", ".ansi.green.bright") --> "#ffc106"
|
||||
--
|
||||
-- theme.get_hex follows 'desktop/colorscheme/get-hex' : an ordered list of lookup terms where
|
||||
-- the first which resolves wins; values which are themselves lookups (".material...") are
|
||||
-- followed recursively; a term is a yq-style path, an ANSI color number (0-15), or one of
|
||||
-- the compatibility terms below; unlike get-hex, colors are returned as "#rrggbb"
|
||||
--
|
||||
-- reads the yaml through 'yq' (dependency of the colorscheme library)
|
||||
|
||||
local DOTWRYN = os.getenv("DOTWRYN")
|
||||
assert(DOTWRYN ~= nil and DOTWRYN ~= "", "DOTWRYN must be set to use the colorscheme library (have you loaded ~/.zshrc?)")
|
||||
|
||||
local COLORSCHEME_DIR = DOTWRYN .. "/config/colorschemes"
|
||||
local ACTIVE_THEME_PATH = COLORSCHEME_DIR .. "/active"
|
||||
local ACTIVE_THEME_SOURCE = ACTIVE_THEME_PATH .. "/source.yaml"
|
||||
local DEFAULT_MATERIAL_REFERENCES = ACTIVE_THEME_PATH .. "/default.yaml"
|
||||
|
||||
local MAX_LOOKUP_RECURSION = 10
|
||||
|
||||
local ANSI_COLOR_LOOKUPS = {
|
||||
[0] = ".ansi.gray.black",
|
||||
[1] = ".ansi.red.regular",
|
||||
[2] = ".ansi.green.regular",
|
||||
[3] = ".ansi.yellow.regular",
|
||||
[4] = ".ansi.blue.regular",
|
||||
[5] = ".ansi.magenta.regular",
|
||||
[6] = ".ansi.cyan.regular",
|
||||
[7] = ".ansi.gray.white",
|
||||
[8] = ".ansi.gray.regular",
|
||||
[9] = ".ansi.red.bright",
|
||||
[10] = ".ansi.green.bright",
|
||||
[11] = ".ansi.yellow.bright",
|
||||
[12] = ".ansi.blue.bright",
|
||||
[13] = ".ansi.magenta.bright",
|
||||
[14] = ".ansi.cyan.bright",
|
||||
[15] = ".ansi.gray.bright",
|
||||
}
|
||||
|
||||
local COMPATIBILITY_LOOKUPS = {
|
||||
foreground = { ".foreground", ".ansi.gray.black" },
|
||||
background = { ".background", ".ansi.gray.white" },
|
||||
cursor = { ".cursor", ".ansi.gray.white" },
|
||||
selection_foreground = { ".selection.foreground", ".background" },
|
||||
selection_background = { ".selection.background", ".foreground" },
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local shell_quote = function(value)
|
||||
return "'" .. value:gsub("'", "'\\''") .. "'"
|
||||
end
|
||||
|
||||
-- (the exit status from pipe:close() is unreliable inside hyprland, which reaps its own
|
||||
-- children; a failed command is detected by its missing output instead)
|
||||
local read_command = function(command)
|
||||
local pipe = io.popen(command)
|
||||
local output = pipe:read("a")
|
||||
pipe:close()
|
||||
if output == nil or output == "" then error("colorscheme : no output from command : " .. command) end
|
||||
return output
|
||||
end
|
||||
|
||||
local read_yaml = function(...)
|
||||
local files = {}
|
||||
for _, file in ipairs({ ... }) do table.insert(files, shell_quote(file)) end
|
||||
|
||||
local chunk = read_command("yq eval-all '. as $item ireduce ({}; . * $item)' -o lua " .. table.concat(files, " "))
|
||||
return assert(load(chunk, "colorscheme", "t", {}))()
|
||||
end
|
||||
|
||||
-- ".material.primary.500" --> values.material.primary[500] (or ["500"])
|
||||
local get_path = function(values, lookup)
|
||||
local value = values
|
||||
for key in lookup:gmatch("[^.]+") do
|
||||
if type(value) ~= "table" then return nil end
|
||||
value = value[tonumber(key)] or value[key]
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
local expand_term = function(term, lookups)
|
||||
local ansi_color = term:match("^%d+$") and ANSI_COLOR_LOOKUPS[tonumber(term)]
|
||||
if ansi_color ~= nil then
|
||||
table.insert(lookups, ansi_color)
|
||||
elseif COMPATIBILITY_LOOKUPS[term] ~= nil then
|
||||
for _, lookup in ipairs(COMPATIBILITY_LOOKUPS[term]) do table.insert(lookups, lookup) end
|
||||
else
|
||||
table.insert(lookups, term)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local colorscheme = {}
|
||||
|
||||
colorscheme.load = function(theme_name)
|
||||
local theme_source = ACTIVE_THEME_SOURCE
|
||||
if theme_name ~= nil then
|
||||
theme_source = COLORSCHEME_DIR .. "/" .. theme_name .. ".yaml"
|
||||
if io.open(theme_source, "r") == nil then error("colorscheme : no such theme '" .. theme_name .. "'") end
|
||||
else
|
||||
-- (name.txt is only written after every theme file is generated)
|
||||
theme_name = read_command("readlink -- " .. shell_quote(ACTIVE_THEME_SOURCE)):match("([^/]+)%.yaml%s*$")
|
||||
end
|
||||
|
||||
local theme = {
|
||||
name = theme_name,
|
||||
values = read_yaml(DEFAULT_MATERIAL_REFERENCES, theme_source),
|
||||
}
|
||||
|
||||
theme.get_hex = function(...)
|
||||
local lookups = {}
|
||||
for _, term in ipairs({ ... }) do expand_term(tostring(term), lookups) end
|
||||
if #lookups == 0 then error("colorscheme : must provide at least one color lookup") end
|
||||
|
||||
for _, lookup in ipairs(lookups) do
|
||||
local value = lookup
|
||||
for _ = 1, MAX_LOOKUP_RECURSION do
|
||||
value = get_path(theme.values, value)
|
||||
if type(value) ~= "string" or value:sub(1, 1) ~= "." then break end
|
||||
end
|
||||
|
||||
if type(value) == "string" and value ~= "" and value:sub(1, 1) ~= "." then
|
||||
return "#" .. value:gsub("^#", "")
|
||||
end
|
||||
end
|
||||
|
||||
error("colorscheme : color lookup error for '" .. table.concat({ ... }, " ") .. "' in theme '" .. tostring(theme.name) .. "'")
|
||||
end
|
||||
|
||||
return theme
|
||||
end
|
||||
|
||||
return colorscheme
|
||||
@@ -8,8 +8,11 @@ ACTIVE_THEME_SOURCE="${ACTIVE_THEME_PATH}/source.yaml"
|
||||
use --group dotwryn desktop/colorscheme/alacritty
|
||||
use --group dotwryn desktop/colorscheme/flameshot
|
||||
use --group dotwryn desktop/colorscheme/getty
|
||||
use --group dotwryn desktop/colorscheme/gtk
|
||||
use --group dotwryn desktop/colorscheme/hyprland
|
||||
use --group dotwryn desktop/colorscheme/kitty
|
||||
use --group dotwryn desktop/colorscheme/polybar
|
||||
use --group dotwryn desktop/colorscheme/quickshell
|
||||
use --group dotwryn desktop/colorscheme/rofi
|
||||
|
||||
COLORSCHEME__SUPPORTED_CONFIG_TYPES=($(typeset -f + | sed -n 's/^_GENERATE_THEME__//p'))
|
||||
@@ -232,8 +235,13 @@ SET_THEME() {
|
||||
[ "${WALLPAPER}" ] && command -v feh &>/dev/null \
|
||||
&& feh --no-fehbg --bg-fill "${WALLPAPER}"
|
||||
|
||||
utils.check-errors --no-usage \
|
||||
utils.check-errors --no-usage || return 1
|
||||
|
||||
# --only regenerates one config type; the active theme (and its name) is unchanged
|
||||
[[ ${UPDATE_ACTIVE_THEME} =~ true ]] \
|
||||
&& echo "${THEME_NAME}" > "${ACTIVE_THEME_PATH}/name.txt"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
_COLORSCHEME_FILE__flameshot="${DOTWRYN}/config/user/flameshot/flameshot.ini"
|
||||
|
||||
_GENERATE_THEME__flameshot() {
|
||||
local C1="#$(_GET_HEX .flameshot.color1 .material.primary.200 .ansi.reg.bright )"
|
||||
local C1="#$(_GET_HEX .flameshot.color1 .material.primary.200 .ansi.red.bright )"
|
||||
local C2="#$(_GET_HEX .flameshot.color2 .material.primary.500 .ansi.red.regular)"
|
||||
local C3="#$(_GET_HEX .flameshot.color3 .material.primary.800 .ansi.green.bright )"
|
||||
local C4="#$(_GET_HEX .flameshot.color4 .material.secondary.200 .ansi.green.regular)"
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
_COLORSCHEME_FILE__gtk3="${DOTWRYN}/config/user/gtk-3.0/gtk.css"
|
||||
_COLORSCHEME_FILE__gtk4="${DOTWRYN}/config/user/gtk-4.0/gtk.css"
|
||||
|
||||
# recolors libadwaita (GTK4) and the adw-gtk3 theme (GTK3) through their shared
|
||||
# named colors; requires gtk-theme-name=adw-gtk3-dark (config/user/gtk-3.0/settings.ini)
|
||||
#
|
||||
# libadwaita draws text from one surface over another (e.g. notebook pages paint the
|
||||
# view background but inherit the window foreground), so every surface shares the
|
||||
# theme foreground and is the theme background tinted toward a material color; the
|
||||
# only bg/fg pairs are the material ones (accent + status colors)
|
||||
_GENERATE_THEME__gtk() {
|
||||
local css="/* do not edit; generated by scwrypts
|
||||
* theme : ${THEME_NAME}
|
||||
*/
|
||||
|
||||
@define-color view_bg_color #$(_GET_HEX .gtk.view.bg .background);
|
||||
@define-color view_fg_color #$(_GET_HEX .gtk.view.fg .foreground);
|
||||
|
||||
@define-color window_bg_color mix(@view_bg_color, #$(_GET_HEX .gtk.window.tint .material.base.secondary .ansi.green.regular ), 0.10);
|
||||
@define-color window_fg_color @view_fg_color;
|
||||
|
||||
@define-color headerbar_bg_color mix(@view_bg_color, #$(_GET_HEX .gtk.headerbar.tint .material.base.primary .ansi.yellow.regular), 0.25);
|
||||
@define-color headerbar_fg_color @view_fg_color;
|
||||
@define-color headerbar_border_color @view_fg_color;
|
||||
@define-color headerbar_backdrop_color @window_bg_color;
|
||||
@define-color headerbar_shade_color rgba(0, 0, 0, 0.36);
|
||||
@define-color headerbar_darker_shade_color rgba(0, 0, 0, 0.9);
|
||||
|
||||
@define-color sidebar_bg_color mix(@view_bg_color, @window_bg_color, 0.6);
|
||||
@define-color sidebar_fg_color @view_fg_color;
|
||||
@define-color sidebar_backdrop_color @view_bg_color;
|
||||
@define-color sidebar_shade_color rgba(0, 0, 0, 0.25);
|
||||
@define-color secondary_sidebar_bg_color @view_bg_color;
|
||||
@define-color secondary_sidebar_fg_color @view_fg_color;
|
||||
|
||||
@define-color card_bg_color alpha(@view_fg_color, 0.05);
|
||||
@define-color card_fg_color @view_fg_color;
|
||||
@define-color card_shade_color rgba(0, 0, 0, 0.36);
|
||||
|
||||
@define-color dialog_bg_color mix(@view_bg_color, @headerbar_bg_color, 0.6);
|
||||
@define-color dialog_fg_color @view_fg_color;
|
||||
|
||||
@define-color popover_bg_color mix(@view_bg_color, @headerbar_bg_color, 0.6);
|
||||
@define-color popover_fg_color @view_fg_color;
|
||||
@define-color popover_shade_color rgba(0, 0, 0, 0.25);
|
||||
|
||||
@define-color thumbnail_bg_color @window_bg_color;
|
||||
@define-color thumbnail_fg_color @view_fg_color;
|
||||
|
||||
@define-color shade_color rgba(0, 0, 0, 0.36);
|
||||
@define-color scrollbar_outline_color rgba(0, 0, 0, 0.5);
|
||||
|
||||
@define-color accent_color #$(_GET_HEX .gtk.accent.color .material.secondary.200 .ansi.green.bright );
|
||||
@define-color accent_bg_color #$(_GET_HEX .gtk.accent.bg .material.base.secondary .ansi.green.regular );
|
||||
@define-color accent_fg_color #$(_GET_HEX .gtk.accent.fg .material.base.foreground.secondary .ansi.gray.white );
|
||||
|
||||
@define-color destructive_color #$(_GET_HEX .gtk.destructive.color .material.error.200 .ansi.red.bright );
|
||||
@define-color destructive_bg_color #$(_GET_HEX .gtk.destructive.bg .material.base.error .ansi.red.regular );
|
||||
@define-color destructive_fg_color #$(_GET_HEX .gtk.destructive.fg .material.base.foreground.error .ansi.gray.white );
|
||||
|
||||
@define-color success_color #$(_GET_HEX .gtk.success.color .material.secondary.200 .ansi.green.bright );
|
||||
@define-color success_bg_color #$(_GET_HEX .gtk.success.bg .material.base.secondary .ansi.green.regular );
|
||||
@define-color success_fg_color #$(_GET_HEX .gtk.success.fg .material.base.foreground.secondary .ansi.gray.white );
|
||||
|
||||
@define-color warning_color #$(_GET_HEX .gtk.warning.color .material.primary.200 .ansi.yellow.bright );
|
||||
@define-color warning_bg_color #$(_GET_HEX .gtk.warning.bg .material.base.primary .ansi.yellow.regular);
|
||||
@define-color warning_fg_color #$(_GET_HEX .gtk.warning.fg .material.base.foreground.primary .ansi.gray.white );
|
||||
|
||||
@define-color error_color #$(_GET_HEX .gtk.error.color .material.error.200 .ansi.red.bright );
|
||||
@define-color error_bg_color #$(_GET_HEX .gtk.error.bg .material.base.error .ansi.red.regular );
|
||||
@define-color error_fg_color #$(_GET_HEX .gtk.error.fg .material.base.foreground.error .ansi.gray.white );"
|
||||
|
||||
# adw-gtk3 pins the GTK4 accent to the system accent-color (libadwaita-tweaks.css)
|
||||
local gtk4_accent="
|
||||
:root {
|
||||
--accent-color: @accent_color;
|
||||
--accent-bg-color: @accent_bg_color;
|
||||
--accent-fg-color: @accent_fg_color;
|
||||
}"
|
||||
|
||||
mkdir -p -- "${_COLORSCHEME_FILE__gtk3:h}" "${_COLORSCHEME_FILE__gtk4:h}"
|
||||
echo "${css}" > "${_COLORSCHEME_FILE__gtk3}"
|
||||
echo "${css}${gtk4_accent}" > "${_COLORSCHEME_FILE__gtk4}"
|
||||
}
|
||||
|
||||
_SET_THEME__gtk() {
|
||||
return 0 # gtk apps load gtk.css on startup
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
_COLORSCHEME_FILE__hyprland_hyprlock="${ACTIVE_THEME_PATH}/hyprlock.conf"
|
||||
_COLORSCHEME_FILE__hyprland_hyprtoolkit="${ACTIVE_THEME_PATH}/hyprtoolkit.conf" # linked to ~/.config/hypr by system/symlinks/get-all
|
||||
|
||||
_GENERATE_THEME__hyprland() {
|
||||
# (hyprland itself reads the colorscheme through colorscheme.lua; see config/desktop/hyprland/config.d/99-dwindle.lua)
|
||||
|
||||
echo "# do not edit; generated by scwrypts
|
||||
# theme : ${THEME_NAME}
|
||||
\$background = rgb($(_GET_HEX .hyprland.hyprlock.background .background))
|
||||
\$foreground = rgb($(_GET_HEX .hyprland.hyprlock.foreground .foreground))
|
||||
\$accent = rgb($(_GET_HEX .hyprland.hyprlock.accent .material.secondary.500 .ansi.green.bright))
|
||||
\$accent_alt = rgb($(_GET_HEX .hyprland.hyprlock.accent-alt .material.primary.700 .ansi.yellow.regular))
|
||||
\$verifying = rgb($(_GET_HEX .hyprland.hyprlock.verifying .material.secondary.200 .ansi.green.bright))
|
||||
\$wrong = rgb($(_GET_HEX .hyprland.hyprlock.wrong .material.error.200 .ansi.red.bright))
|
||||
\$keypress = rgb($(_GET_HEX .hyprland.hyprlock.keypress .material.primary.200 .ansi.yellow.bright))
|
||||
\$clock = rgb($(_GET_HEX .hyprland.hyprlock.clock .ansi.gray.white))
|
||||
\$date = rgb($(_GET_HEX .hyprland.hyprlock.date .ansi.gray.bright))" > "${_COLORSCHEME_FILE__hyprland_hyprlock}"
|
||||
|
||||
# shared theme for hyprland-ecosystem GUI apps (hyprland-guiutils dialogs, hyprpm prompts, ...)
|
||||
echo "# do not edit; generated by scwrypts
|
||||
# theme : ${THEME_NAME}
|
||||
background = rgb($(_GET_HEX .hyprland.hyprtoolkit.background .material.secondary.900 .ansi.gray.black))
|
||||
base = rgb($(_GET_HEX .hyprland.hyprtoolkit.base .material.secondary.900 .ansi.gray.black))
|
||||
alternate_base = rgb($(_GET_HEX .hyprland.hyprtoolkit.alternate-base .background))
|
||||
text = rgb($(_GET_HEX .hyprland.hyprtoolkit.text .material.foreground.secondary.900 .ansi.gray.white))
|
||||
bright_text = rgb($(_GET_HEX .hyprland.hyprtoolkit.bright-text .material.foreground.primary.300 .ansi.gray.black))
|
||||
accent = rgb($(_GET_HEX .hyprland.hyprtoolkit.accent .material.primary.300 .ansi.yellow.bright))
|
||||
accent_secondary = rgb($(_GET_HEX .hyprland.hyprtoolkit.accent-secondary .material.base.primary .ansi.yellow.regular))
|
||||
|
||||
font_family = Monaspace Argon
|
||||
font_family_monospace = Monaspace Argon
|
||||
|
||||
rounding_large = 0
|
||||
rounding_small = 0" > "${_COLORSCHEME_FILE__hyprland_hyprtoolkit}"
|
||||
}
|
||||
|
||||
_SET_THEME__hyprland() {
|
||||
command -v hyprctl &>/dev/null || return 0
|
||||
|
||||
# shells that outlive a hyprland start (e.g. a tmux server started from the TTY)
|
||||
# don't carry its environment; fall back to the most recent running instance
|
||||
local -x HYPRLAND_INSTANCE_SIGNATURE="${HYPRLAND_INSTANCE_SIGNATURE:-$(
|
||||
hyprctl instances -j 2>/dev/null | jq -r 'sort_by(.time) | last | .instance // empty'
|
||||
)}"
|
||||
[[ "${HYPRLAND_INSTANCE_SIGNATURE}" ]] || return 0 # hyprland isn't running
|
||||
|
||||
hyprctl reload &>/dev/null
|
||||
scwrypts --group dotwryn --type zsh --name desktop/wayland/hyprland/set-background -- theme "${THEME_NAME}" &>/dev/null # name.txt is written after this hook
|
||||
return 0
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
_COLORSCHEME_FILE__quickshell="${DOTWRYN}/config/user/quickshell/colors.json"
|
||||
|
||||
_GENERATE_THEME__quickshell() {
|
||||
echo "{
|
||||
\"theme\" : \"${THEME_NAME}\",
|
||||
\"background\" : \"#$(_GET_HEX .quickshell.background .background)\",
|
||||
\"foreground\" : \"#$(_GET_HEX .quickshell.foreground .foreground)\",
|
||||
\"backgroundAlt\" : \"#$(_GET_HEX .quickshell.background-alt .selection.background)\",
|
||||
\"foregroundAlt\" : \"#$(_GET_HEX .quickshell.foreground-alt .selection.foreground)\",
|
||||
\"primary\" : \"#$(_GET_HEX .quickshell.primary .material.base.primary .ansi.yellow.regular)\",
|
||||
\"secondary\" : \"#$(_GET_HEX .quickshell.secondary .material.base.secondary .ansi.green.regular)\",
|
||||
\"alert\" : \"#$(_GET_HEX .quickshell.alert .material.base.error .ansi.red.regular)\",
|
||||
\"disabled\" : \"#$(_GET_HEX .quickshell.disabled .ansi.gray.regular)\",
|
||||
|
||||
\"secondaryGradient\" : [
|
||||
\"#$(_GET_HEX .quickshell.secondary-gradient-0 .material.secondary.700 .ansi.green.regular)\",
|
||||
\"#$(_GET_HEX .quickshell.secondary-gradient-1 .material.secondary.600 .ansi.green.regular)\",
|
||||
\"#$(_GET_HEX .quickshell.secondary-gradient-2 .material.secondary.500 .ansi.green.regular)\",
|
||||
\"#$(_GET_HEX .quickshell.secondary-gradient-3 .material.secondary.400 .ansi.green.regular)\",
|
||||
\"#$(_GET_HEX .quickshell.secondary-gradient-4 .material.secondary.300 .ansi.green.regular)\"
|
||||
]
|
||||
}" > "${_COLORSCHEME_FILE__quickshell}"
|
||||
}
|
||||
|
||||
_SET_THEME__quickshell() {
|
||||
return 0 # quickshell watches colors.json and reloads on change
|
||||
}
|
||||
@@ -54,6 +54,7 @@ ${scwryptsmodule}() {
|
||||
# ---------------------------------------------- | -------------------------------------------------
|
||||
echo "
|
||||
${DOTWRYN}/config/scwrypts/config.zsh ${XDG_CONFIG_HOME}/scwrypts/config.zsh
|
||||
${DOTWRYN}/config/colorschemes/active/hyprtoolkit.conf ${XDG_CONFIG_HOME}/hypr/hyprtoolkit.conf
|
||||
"
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user