aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/fix-systemsettings-lua.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/fix-systemsettings-lua.sh')
-rwxr-xr-xscripts/fix-systemsettings-lua.sh229
1 files changed, 229 insertions, 0 deletions
diff --git a/scripts/fix-systemsettings-lua.sh b/scripts/fix-systemsettings-lua.sh
new file mode 100755
index 00000000..e1b550fc
--- /dev/null
+++ b/scripts/fix-systemsettings-lua.sh
@@ -0,0 +1,229 @@
+#!/usr/bin/env bash
+# ==================================================
+# KoolDots (2026)
+# Project URL: https://github.com/LinuxBeginnings
+# License: GNU GPLv3
+# SPDX-License-Identifier: GPL-3.0-or-later
+# ==================================================
+# Regenerate ~/.config/hypr/configs/system_settings.lua from SystemSettings.conf.
+
+set -euo pipefail
+
+CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
+HYPR_DIR="${CONFIG_HOME}/hypr"
+CONFIGS_DIR="${HYPR_DIR}/configs"
+LEGACY_DIR="${CONFIGS_DIR}/LegacyConfigs"
+SYSTEM_SETTINGS_CONF="${CONFIGS_DIR}/SystemSettings.conf"
+SYSTEM_SETTINGS_LUA="${CONFIGS_DIR}/system_settings.lua"
+
+python3 - <<'PY'
+from pathlib import Path
+import os
+import re
+
+HEADER = """-- ==================================================
+-- KoolDots (2026)
+-- Project URL: https://github.com/LinuxBeginnings
+-- License: GNU GPLv3
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- ==================================================
+"""
+
+config_home = Path(os.getenv("XDG_CONFIG_HOME") or (Path.home() / ".config"))
+hypr_dir = config_home / "hypr"
+configs_dir = hypr_dir / "configs"
+legacy_dir = configs_dir / "LegacyConfigs"
+system_settings_path = configs_dir / "SystemSettings.conf"
+output_path = configs_dir / "system_settings.lua"
+
+def strip_comment(line: str) -> str:
+ return line.split("#", 1)[0].strip()
+
+def lua_string(value: str) -> str:
+ return '"' + value.replace("\\", "\\\\").replace('"', '\\"') + '"'
+
+def scalar(value: str, *, bool_words: bool = True) -> str:
+ value = value.strip()
+ lower = value.lower()
+ if bool_words and lower in {"on", "true", "yes"}:
+ return "true"
+ if bool_words and lower in {"off", "false", "no"}:
+ return "false"
+ if re.fullmatch(r"[-+]?\d+(\.\d+)?", value):
+ return value
+ return lua_string(value)
+
+def render_table(value, indent=4):
+ lines = []
+ for key, child in value.items():
+ if isinstance(child, dict):
+ lines.append(" " * indent + f"{key} = {{")
+ lines.extend(render_table(child, indent + 2))
+ lines.append(" " * indent + "},")
+ else:
+ lines.append(" " * indent + f"{key} = {scalar(str(child))},")
+ return lines
+
+def latest_legacy_file(path: Path):
+ if not legacy_dir.is_dir():
+ return None
+ candidates = []
+ for snapshot in sorted(legacy_dir.iterdir()):
+ if not snapshot.is_dir():
+ continue
+ candidate = snapshot / path.name
+ if candidate.is_file():
+ candidates.append(candidate)
+ return candidates[-1] if candidates else None
+
+def parse_hyprlang_sections(path: Path):
+ sections = {}
+ if path is None or not path.exists():
+ return sections
+ stack = [sections]
+ for raw in path.read_text(encoding="utf-8", errors="ignore").splitlines():
+ line = strip_comment(raw)
+ if not line:
+ continue
+ if line.startswith("source"):
+ continue
+ if line.endswith("{"):
+ name = line[:-1].strip().replace("-", "_")
+ if not name or name.startswith("$"):
+ continue
+ current = stack[-1]
+ target = current.setdefault(name, {})
+ stack.append(target)
+ continue
+ if line == "}":
+ if len(stack) > 1:
+ stack.pop()
+ continue
+ if "=" in line:
+ key, value = [part.strip() for part in line.split("=", 1)]
+ if not key or key.startswith("$"):
+ continue
+ key = key.replace("-", "_")
+ container = stack[-1]
+ parts = [part.replace("-", "_") for part in key.split(".") if part]
+ for part in parts[:-1]:
+ container = container.setdefault(part, {})
+ container[parts[-1]] = value
+ return sections
+
+def parse_scripts_dir(path: Path):
+ if path is None or not path.exists():
+ return None
+ for raw in path.read_text(encoding="utf-8", errors="ignore").splitlines():
+ line = strip_comment(raw)
+ if not line:
+ continue
+ match = re.match(r"^\$scriptsDir\s*=\s*(.+)$", line)
+ if match:
+ value = match.group(1).strip().strip('"').strip("'")
+ return value
+ return None
+
+def parse_gestures(path: Path):
+ simple = []
+ complex_entries = []
+ if path is None or not path.exists():
+ return simple, complex_entries
+ for raw in path.read_text(encoding="utf-8", errors="ignore").splitlines():
+ line = strip_comment(raw)
+ if not line:
+ continue
+ match = re.match(r"^gesture\s*=\s*(.+)$", line)
+ if not match:
+ continue
+ payload = match.group(1).strip()
+ parts = [part.strip() for part in payload.split(",")]
+ if len(parts) >= 3 and parts[2] == "workspace":
+ try:
+ fingers = int(parts[0])
+ except ValueError:
+ complex_entries.append(payload)
+ continue
+ simple.append({"fingers": fingers, "direction": parts[1], "action": "workspace"})
+ else:
+ complex_entries.append(payload)
+ return simple, complex_entries
+
+source_path = system_settings_path if system_settings_path.exists() else latest_legacy_file(system_settings_path)
+
+lines = [
+ "-- System Settings (auto-generated).",
+ "-- This file keeps migrated settings split from user overrides.",
+ "-- Add only Lua entries here.",
+ "-- Example:",
+ "-- hl.config({ general = { gaps_in = 4, gaps_out = 8 } })",
+ "",
+]
+
+if source_path is None:
+ lines.append("-- No active entries were found in SystemSettings.conf.")
+else:
+ scripts_dir = parse_scripts_dir(source_path)
+ if scripts_dir:
+ lines.append(f"local scriptsDir = {lua_string(scripts_dir)}")
+ lines.append("")
+
+ sections = parse_hyprlang_sections(source_path)
+ gestures_section = sections.pop("gestures", None)
+ if gestures_section and "gesture" in gestures_section:
+ gestures_section.pop("gesture", None)
+
+ ordered_sections = [
+ "dwindle",
+ "master",
+ "scrolling",
+ "general",
+ "input",
+ "gestures",
+ "misc",
+ "binds",
+ "xwayland",
+ "render",
+ "cursor",
+ ]
+ for section in ordered_sections:
+ if section == "gestures":
+ data = gestures_section
+ elif section == "misc":
+ data = sections.get(section) or {}
+ if "force_default_wallpaper" not in data:
+ data["force_default_wallpaper"] = "false"
+ else:
+ data = sections.get(section)
+ if not data:
+ continue
+ lines.append("hl.config({")
+ lines.append(f" {section} = {{")
+ lines.extend(render_table(data, indent=4))
+ lines.append(" },")
+ lines.append("})")
+ lines.append("")
+
+ simple_gestures, complex_gestures = parse_gestures(source_path)
+ for spec in simple_gestures:
+ lines.extend([
+ "hl.gesture({",
+ f" fingers = {spec['fingers']},",
+ f" direction = {lua_string(spec['direction'])},",
+ f" action = {lua_string(spec['action'])},",
+ "})",
+ "",
+ ])
+
+ if complex_gestures:
+ lines.append("-- Complex dispatcher gestures from SystemSettings.conf are pending explicit Lua API parity:")
+ for entry in complex_gestures:
+ lines.append(f"-- gesture = {entry}")
+ lines.append("")
+
+content = "\n".join(lines).rstrip() + "\n"
+if not content.startswith(HEADER):
+ content = HEADER + "\n" + content.lstrip("\n")
+output_path.write_text(content, encoding="utf-8")
+print(f"[OK] Wrote {output_path}")
+PY
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage