summaryrefslogtreecommitdiffhomepage
path: root/packages/ext-keybindings/src/config.cpp
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-13 23:23:15 +0900
committerAdam Malczewski <[email protected]>2026-06-13 23:23:15 +0900
commitcc85e7a6f338b78a399b960c8f2f9e634cef76bf (patch)
treef17dbb9007b7ea57af4b60a89d955f41f5a0d035 /packages/ext-keybindings/src/config.cpp
parent35e5d32901c9a35700d3d8b046971dafc9bed5fe (diff)
downloadunbox-cc85e7a6f338b78a399b960c8f2f9e634cef76bf.tar.gz
unbox-cc85e7a6f338b78a399b960c8f2f9e634cef76bf.zip
ext-keybindings: hot-reload unbox.toml (live config, no restart)
Editing the config now re-applies keybindings live, via the kernel's watch_file service. In activate() we watch the effective config path (the create() arg, else ~/.config/unbox/unbox.toml) — even if it doesn't exist yet, so creating it later is picked up — holding the FileWatch as a member. On change, reload_config() re-reads + re-parses (the existing pure toml core) and SWAPs the live binding table the key_filter link matches against (matcher_), so new bindings apply with no re-subscribe. A malformed / unreadable / mid-edit-broken file KEEPS the current bindings and logs one warning — the session never loses working keys, never throws. Real-seat verified: editing the command (fuzzel->foot) logged "config reloaded (5 binding(s))" live; a deliberately broken file logged "reload failed; keeping current bindings" with the session staying ALIVE; restoring it recovered. Added a pure reload-semantics doctest (A->B swap; malformed keeps prior). ext-keybindings 2/2 green on build + build-asan. Edits confined to packages/ext-keybindings/.
Diffstat (limited to 'packages/ext-keybindings/src/config.cpp')
-rw-r--r--packages/ext-keybindings/src/config.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/packages/ext-keybindings/src/config.cpp b/packages/ext-keybindings/src/config.cpp
index 4d1045f..726b24b 100644
--- a/packages/ext-keybindings/src/config.cpp
+++ b/packages/ext-keybindings/src/config.cpp
@@ -101,4 +101,25 @@ auto load_from_string(std::string_view toml_text) -> LoadResult {
return result;
}
+auto reload_bindings(const std::vector<policy::Binding>& current, std::string_view toml_text)
+ -> ReloadDecision {
+ ReloadDecision decision;
+ LoadResult loaded = load_from_string(toml_text);
+ decision.warnings = std::move(loaded.warnings);
+
+ // KEEP-OLD on a syntax error or on a parse that produced no usable bindings
+ // (an empty file, a [[keybind]]-less doc, or one where every entry was
+ // skipped). Either way the live table must remain the user's working keys.
+ if (loaded.parse_error || loaded.bindings.empty()) {
+ decision.bindings = current; // unchanged copy
+ decision.swapped = false;
+ return decision;
+ }
+
+ // SUCCESS: the new table replaces the live one (the swap).
+ decision.bindings = std::move(loaded.bindings);
+ decision.swapped = true;
+ return decision;
+}
+
} // namespace unbox::ext_keybindings::config