Matugen: a lot of cleanup and refactoring, splitting scripts into

separate functions
This commit is contained in:
lysec
2025-10-06 17:05:08 +02:00
parent 48d0fb3266
commit 49c7eefe63
3 changed files with 172 additions and 130 deletions
+5 -7
View File
@@ -5,7 +5,7 @@
if [ "$#" -ne 1 ]; then
# Print usage information to standard error.
echo "Error: No application specified." >&2
echo "Usage: $0 {kitty|ghostty|foot|fuzzell|pywalfox}" >&2
echo "Usage: $0 {kitty|ghostty|foot|fuzzel|pywalfox}" >&2
exit 1
fi
@@ -50,8 +50,8 @@ case "$APP_NAME" in
fi
;;
fuzzell)
echo "🎨 Applying 'noctalia' theme to fuzzell..."
fuzzel)
echo "🎨 Applying 'noctalia' theme to fuzzel..."
CONFIG_FILE="$HOME/.config/fuzzel/fuzzel.ini"
# Check if the config file exists.
@@ -61,7 +61,7 @@ case "$APP_NAME" in
# Add the new theme include line.
echo "include=~/.config/fuzzel/themes/noctalia" >> "$CONFIG_FILE"
else
echo "Error: fuzzell config file not found at $CONFIG_FILE" >&2
echo "Error: fuzzel config file not found at $CONFIG_FILE" >&2
exit 1
fi
;;
@@ -78,6 +78,4 @@ case "$APP_NAME" in
;;
esac
echo "✅ Command sent for $APP_NAME."
# lines.push("post_hook = \"grep -q '^theme *= *' ~/.config/ghostty/config; and sed -i 's/^theme *= *.*/theme = noctalia/' ~/.config/ghostty/config; or echo 'theme = noctalia' >> ~/.config/ghostty/config; and pkill -SIGUSR2 ghostty\"")
echo "✅ Command sent for $APP_NAME."
+76 -51
View File
@@ -46,6 +46,7 @@ Singleton {
// Generate colors using current wallpaper and settings
function generateFromWallpaper() {
Logger.log("Matugen", "Generating from wallpaper on screen:", Screen.name)
var wp = WallpaperService.getWallpaper(Screen.name).replace(/'/g, "'\\''")
if (wp === "") {
Logger.error("Matugen", "No wallpaper was found")
@@ -55,26 +56,47 @@ Singleton {
var content = MatugenTemplates.buildConfigToml()
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
var pathEsc = dynamicConfigPath.replace(/'/g, "'\\''")
var extraRepo = (Quickshell.shellDir + "/Assets/Matugen/extra").replace(/'/g, "'\\''")
var extraUser = (Settings.configDir + "matugen.d").replace(/'/g, "'\\''")
// Build the main script
var script = "cat > '" + pathEsc + "' << 'EOF'\n" + content + "EOF\n" + "for d in '" + extraRepo + "' '" + extraUser + "'; do\n" + " if [ -d \"$d\" ]; then\n" + " for f in \"$d\"/*.toml; do\n" + " [ -f \"$f\" ] && { echo; echo \"# extra: $f\"; cat \"$f\"; } >> '" + pathEsc + "'\n" + " done\n" + " fi\n"
+ "done\n" + "matugen image '" + wp + "' --config '" + pathEsc + "' --mode " + mode + " --type " + Settings.data.colorSchemes.matugenSchemeType
var script = buildMatugenScript(content, pathEsc, wp, mode)
// Add user config execution if enabled
if (Settings.data.templates.enableUserTemplates) {
var userConfigDir = (Quickshell.env("HOME") + "/.config/matugen/").replace(/'/g, "'\\''")
script += "\n# Execute user config if it exists\nif [ -f '" + userConfigDir + "config.toml' ]; then\n"
script += " matugen image '" + wp + "' --config '" + userConfigDir + "config.toml' --mode " + mode + " --type " + Settings.data.colorSchemes.matugenSchemeType + "\n"
script += "fi"
}
script += "\n"
generateProcess.command = ["bash", "-lc", script]
generateProcess.running = true
}
// --------------------------------
function buildMatugenScript(content, pathEsc, wallpaper, mode) {
var script = "cat > '" + pathEsc + "' << 'EOF'\n" + content + "EOF\n"
// Main matugen command
script += "matugen image '" + wallpaper + "' --config '" + pathEsc + "' --mode " + mode + " --type " + Settings.data.colorSchemes.matugenSchemeType
// Add user template execution if enabled
script += addUserTemplateExecution(wallpaper, mode)
return script + "\n"
}
// --------------------------------
function addUserTemplateExecution(input, mode) {
if (!Settings.data.templates.enableUserTemplates) {
return ""
}
var userConfigPath = getUserConfigPath()
var script = "\n# Execute user config if it exists\n"
script += "if [ -f '" + userConfigPath + "' ]; then\n"
script += " matugen image '" + input + "' --config '" + userConfigPath + "' --mode " + mode + " --type " + Settings.data.colorSchemes.matugenSchemeType + "\n"
script += "fi"
return script
}
// --------------------------------
function getUserConfigPath() {
return (Quickshell.env("HOME") + "/.config/matugen/config.toml").replace(/'/g, "'\\''")
}
// --------------------------------
function selectVibrantColor(schemeData, mode) {
var colors = []
@@ -106,63 +128,67 @@ Singleton {
var content = MatugenTemplates.buildConfigToml()
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
var pathEsc = dynamicConfigPath.replace(/'/g, "'\\''")
var extraRepo = (Quickshell.shellDir + "/Assets/Matugen/extra").replace(/'/g, "'\\''")
var extraUser = (Settings.configDir + "matugen.d").replace(/'/g, "'\\''")
const color = selectVibrantColor(schemeData, mode)
// Build the script
var script = ""
script += "cat > '" + pathEsc + "' << 'EOF'\n" + content + "EOF\n\n"
// script += "for d in '" + extraRepo + "' '" + extraUser + "'; do\n"
// script += " if [ -d \"$d\" ]; then\n"
// script += " for f in \"$d\"/*.toml; do\n"
// script += " [ -f \"$f\" ] && { echo; echo \"# extra: $f\"; cat \"$f\"; } >> '" + pathEsc + "'\n"
// script += " done\n"
// script += " fi\n"
// script += "done\n\n"
script += "matugen color hex '" + color + "' --config '" + pathEsc + "' --mode " + mode
var script = buildPredefinedSchemeScript(content, pathEsc, color, mode)
console.log(script)
// // Add user config execution if enabled
// if (Settings.data.templates.enableUserTemplates) {
// var userConfigDir = (Quickshell.env("HOME") + "/.config/matugen/").replace(/'/g, "'\\''")
// script += "\n# Execute user config if it exists\nif [ -f '" + userConfigDir + "config.toml' ]; then\n"
// script += " matugen color hex " + color + " --config '" + userConfigDir + "config.toml' --mode " + mode
// script += "fi"
// }
script += "\n"
generateProcess.command = ["bash", "-lc", script]
generateProcess.running = true
// -----
// Handle terminal theme copying for predefined schemes
handleTerminalThemes()
}
// --------------------------------
function buildPredefinedSchemeScript(content, pathEsc, color, mode) {
var script = "cat > '" + pathEsc + "' << 'EOF'\n" + content + "EOF\n\n"
script += "matugen color hex '" + color + "' --config '" + pathEsc + "' --mode " + mode + "\n"
// Add user template execution if enabled
script += addUserTemplateExecutionForColor(color, mode)
return script
}
// --------------------------------
function addUserTemplateExecutionForColor(color, mode) {
if (!Settings.data.templates.enableUserTemplates) {
return ""
}
var userConfigPath = getUserConfigPath()
var script = "\n# Execute user config if it exists\n"
script += "if [ -f '" + userConfigPath + "' ]; then\n"
script += " matugen color hex '" + color + "' --config '" + userConfigPath + "' --mode " + mode + "\n"
script += "fi"
return script
}
// --------------------------------
function handleTerminalThemes() {
var terminals = {
foot: "~/.config/foot/themes/noctalia",
ghostty: "/.config/ghostty/themes/noctalia",
ghostty: "~/.config/ghostty/themes/noctalia",
kitty: "~/.config/kitty/themes/noctalia.conf",
}
var copyCmd = Object.entries(terminals)
.filter(([terminal, colorsPath]) => Settings.data.templates[terminal])
.map(([terminal, colorsPath]) => {
// regex matches everything after last '/' in a string
var colorsPathParent = colorsPath.replace(/[^\/]*$/, "")
var terminalColorsTemplate = getTerminalColorsTemplate(terminal)
return [
// make sure intermediate theme directories are present
`mkdir -p ${colorsPathParent}`,
// copy theme file to terminal config directory
`cp -f ${terminalColorsTemplate} ${colorsPath}`,
// apply theme config
`${colorsApplyScript} ${terminal}`,
]
})
.reduce((arr1, arr2) => arr1.concat(arr2), []) // can't use .flatMap in Qt's environment
.reduce((arr1, arr2) => arr1.concat(arr2), [])
.join("; ")
if (copyCmd !== "") {
//console.log(copyCmd)
copyProcess.command = ["bash", "-lc", copyCmd]
copyProcess.running = true
}
@@ -174,14 +200,13 @@ Singleton {
const darkLight = Settings.data.colorSchemes.darkMode ? 'dark' : 'light'
// Convert display names back to folder names
if (colorScheme === "Noctalia (default)") {
colorScheme = "Noctalia-default"
} else if (colorScheme === "Noctalia (legacy)") {
colorScheme = "Noctalia-legacy"
} else if (colorScheme === "Tokyo Night") {
colorScheme = "Tokyo-Night"
var schemeMap = {
"Noctalia (default)": "Noctalia-default",
"Noctalia (legacy)": "Noctalia-legacy",
"Tokyo Night": "Tokyo-Night"
}
colorScheme = schemeMap[colorScheme] || colorScheme
var extension = terminal === 'kitty' ? ".conf" : ""
return `${Quickshell.shellDir}/Assets/ColorScheme/${colorScheme}/terminal/${terminal}/${colorScheme}-${darkLight}${extension}`
+91 -72
View File
@@ -6,8 +6,11 @@ import qs.Commons
// Central place to define which templates we generate and where they write.
// Users can extend it by dropping additional templates into:
// - Assets/MatugenTemplates/
// - ~/.config/matugen/ (when enableUserTemplates is true)
// - Assets/MatugenTemplates/ (built-in templates)
// - ~/.config/matugen/ (user-defined templates when enableUserTemplates is true)
//
// User templates are automatically executed after the main matugen command
// if enableUserTemplates is enabled in settings.
Singleton {
id: root
@@ -15,81 +18,97 @@ Singleton {
function buildConfigToml() {
var lines = []
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
lines.push("[config]")
if (Settings.data.colorSchemes.useWallpaperColors) {
// Only generate colors for Noctalia if the colors are wallpaper based
// or this will conflict with our predefined colors
lines.push("[templates.noctalia]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/noctalia.json"')
lines.push('output_path = "' + Settings.configDir + 'colors.json"')
// Only generate colors for terminalk if the colors are wallpaper based
// predefined color schemes use a different approach for better result
if (Settings.data.templates.foot) {
lines.push("\n[templates.foot]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/Terminal/foot"')
lines.push('output_path = "~/.config/foot/themes/noctalia"')
lines.push(`post_hook = "${MatugenService.colorsApplyScript} foot"`)
}
if (Settings.data.templates.ghostty) {
lines.push("\n[templates.ghostty]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/Terminal/ghostty"')
lines.push('output_path = "~/.config/ghostty/themes/noctalia"')
lines.push(`post_hook = "${MatugenService.colorsApplyScript} ghostty"`)
}
if (Settings.data.templates.kitty) {
lines.push("\n[templates.kitty]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/Terminal/kitty.conf"')
lines.push('output_path = "~/.config/kitty/themes/noctalia.conf"')
lines.push(`post_hook = "${MatugenService.colorsApplyScript} kitty"`)
}
}
if (Settings.data.templates.gtk) {
lines.push("\n[templates.gtk3]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/gtk.css"')
lines.push('output_path = "~/.config/gtk-3.0/gtk.css"')
lines.push("post_hook = 'gsettings set org.gnome.desktop.interface color-scheme prefer-" + mode + "'")
lines.push("\n[templates.gtk4]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/gtk.css"')
lines.push('output_path = "~/.config/gtk-4.0/gtk.css"')
lines.push("post_hook = 'gsettings set org.gnome.desktop.interface color-scheme prefer-" + mode + "'")
}
if (Settings.data.templates.qt) {
lines.push("\n[templates.qt5]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/qtct.conf"')
lines.push('output_path = "~/.config/qt5ct/colors/noctalia.conf"')
lines.push("\n[templates.qt6]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/qtct.conf"')
lines.push('output_path = "~/.config/qt6ct/colors/noctalia.conf"')
}
if (Settings.data.templates.fuzzel) {
lines.push("\n[templates.fuzzel]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/fuzzel.conf"')
lines.push('output_path = "~/.config/fuzzel/themes/noctalia"')
lines.push(`post_hook = "${MatugenService.colorsApplyScript} fuzzel"`)
}
if (Settings.data.templates.pywalfox) {
lines.push("\n[templates.pywalfox]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/pywalfox.json"')
lines.push('output_path = "~/.cache/wal/colors.json"')
lines.push(`post_hook = "${MatugenService.colorsApplyScript} pywalfox"`)
}
if (Settings.data.templates.vesktop) {
lines.push("\n[templates.vesktop]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/vesktop.css"')
lines.push('output_path = "~/.config/vesktop/themes/noctalia.theme.css"')
addWallpaperBasedTemplates(lines, mode)
}
addApplicationTemplates(lines, mode)
return lines.join("\n") + "\n"
}
// --------------------------------
function addWallpaperBasedTemplates(lines, mode) {
// Noctalia colors
lines.push("[templates.noctalia]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/noctalia.json"')
lines.push('output_path = "' + Settings.configDir + 'colors.json"')
// Terminal templates (only for wallpaper-based colors)
addTerminalTemplates(lines)
}
// --------------------------------
function addTerminalTemplates(lines) {
var terminals = [
{ name: "foot", path: "Terminal/foot", output: "~/.config/foot/themes/noctalia" },
{ name: "ghostty", path: "Terminal/ghostty", output: "~/.config/ghostty/themes/noctalia" },
{ name: "kitty", path: "Terminal/kitty.conf", output: "~/.config/kitty/themes/noctalia.conf" }
]
terminals.forEach(function(terminal) {
if (Settings.data.templates[terminal.name]) {
lines.push("\n[templates." + terminal.name + "]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/' + terminal.path + '"')
lines.push('output_path = "' + terminal.output + '"')
lines.push('post_hook = "' + MatugenService.colorsApplyScript + " " + terminal.name + '"')
}
})
}
// --------------------------------
function addApplicationTemplates(lines, mode) {
var applications = [
{
name: "gtk",
templates: [
{ version: "gtk3", output: "~/.config/gtk-3.0/gtk.css" },
{ version: "gtk4", output: "~/.config/gtk-4.0/gtk.css" }
],
input: "gtk.css",
postHook: "gsettings set org.gnome.desktop.interface color-scheme prefer-" + mode
},
{
name: "qt",
templates: [
{ version: "qt5", output: "~/.config/qt5ct/colors/noctalia.conf" },
{ version: "qt6", output: "~/.config/qt6ct/colors/noctalia.conf" }
],
input: "qtct.conf"
},
{
name: "fuzzel",
templates: [{ version: "fuzzel", output: "~/.config/fuzzel/themes/noctalia" }],
input: "fuzzel.conf",
postHook: MatugenService.colorsApplyScript + " fuzzel"
},
{
name: "pywalfox",
templates: [{ version: "pywalfox", output: "~/.cache/wal/colors.json" }],
input: "pywalfox.json",
postHook: MatugenService.colorsApplyScript + " pywalfox"
},
{
name: "vesktop",
templates: [{ version: "vesktop", output: "~/.config/vesktop/themes/noctalia.theme.css" }],
input: "vesktop.css"
}
]
applications.forEach(function(app) {
if (Settings.data.templates[app.name]) {
app.templates.forEach(function(template) {
lines.push("\n[templates." + template.version + "]")
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/MatugenTemplates/' + app.input + '"')
lines.push('output_path = "' + template.output + '"')
if (app.postHook) {
lines.push('post_hook = "' + app.postHook + '"')
}
})
}
})
}
}