config: route the builtin through the registry and repair the designed subsystem syncs#358
Merged
Merged
Conversation
config get/set iterated only the legacy config_options[] array and never consulted the CREG registry, so registry-only keys -- completion.chain_directories, completion.menu_shadow_ghost, and every future CREG-only key -- reported "Unknown configuration key". The central configuration system is meant to be the single, discoverable source of truth every surface shares; the builtin bypassing it broke that contract. Add a registry fallback to config_get_value and config_set_value: after the legacy table misses, consult config_registry_get/set. get prints by value type; set probes the declared type, parses the text against it (boolean widened to true/1/on/yes and false/0/off/no, integers via strtoll with overflow and trailing-garbage checks), writes through the registry (firing its change notification), then mirrors into the runtime struct and applies. Every previously working key resolves exactly as before; the fallback runs only when the legacy table misses, so this is purely additive and makes the CREG-only keys reachable without changing existing behavior. First step toward a single config table: the legacy array shrinks as its keys migrate into the registry, after which this fallback becomes the primary path.
display lle hot-reload and display lle pager write their state to both the runtime
struct and the config registry, and display_sync_to/from_runtime already mirror
display.theme_hot_reload and display.lle.pager.{enabled,min_lines,wrap_search}
between the registry and the struct. But those four keys were never registered in
the display section, so every registry write and every sync returned
CREG_ERROR_NOT_FOUND and silently did nothing: the builtins updated the struct
while the registry stayed empty, the settings never persisted to lushrc.toml, and
TOML values for them were dropped on load.
Register the four keys in display_options[] with defaults matching
config_set_defaults. The existing sync hooks become live, so the designed
display-builtin to central-config synchronization works end to end both ways: a
display lle change persists through config save, and a lushrc.toml value reaches
the runtime and shows in display lle status.
config_registry_apply_mode_defaults seeds the registry with the active mode's curated defaults, but nothing pushed them into the runtime struct the engine reads. On a fresh install with no lushrc the user-config load path -- the only caller of config_registry_sync_to_runtime in that flow -- never runs, so the struct kept the generic config_set_defaults values; and apply_mode_preset re-seeded the registry on a mode switch without syncing, stranding the previous mode's value in the struct. Mode-aware options (history.search_mode, the Ctrl-R finder settings, and -- once registered -- completion.match_mode) silently did not follow the active mode. Call config_registry_sync_to_runtime() right after apply_mode_defaults in config_init (before the user-config existence checks), and add sync_to_runtime + config_apply_settings after the re-seed in apply_mode_preset. The active mode's defaults now reach the struct on startup and change with the mode mid-session; user config still layers on top via the later load-path sync.
The completion match predicate and fuzzy-accept threshold lived only in the
legacy config_options[] array and the runtime struct, never in the CREG section.
So the four config_registry_set_mode_default("completion.match_mode", ...) calls
silently failed against an unregistered key, and lush's curated fuzzy default
never applied -- the struct kept the generic prefix default in every mode. A
stale completion_sync_to_runtime comment claimed the key's "registry storage
points directly at config.completion_match_mode", describing a registration and
a storage-pointer model that do not exist.
Register completion.match_mode (string: prefix/substring/fuzzy) and
completion.threshold (integer) in completion_options[], and add real
string<->enum sync in completion_sync_to/from_runtime using the existing
completion_match_mode_mappings table. With the registry sync from the companion
change, lush now resolves to fuzzy and posix/bash/zsh to prefix, both at startup
and across mode switches, observable via config get and the COMPLETION_MATCH_MODE
script variable.
display lle history writes lle.enable_deduplication, lle.dedup_scope, lle.dedup_strategy, lle.dedup_navigation, and lle.dedup_navigation_unique to the registry, but no "lle" section was ever registered, so every config_registry_set returned CREG_ERROR_NOT_FOUND: the builtin updated the struct while the registry stayed empty and the settings never persisted to lushrc.toml. Register an lle section with the six dedup keys (defaults matching config_set_defaults), carrying the two enums (scope, strategy) as strings and translating them onto the engine enums in lle_sync_to/from_runtime via the shared lle_dedup_scope_mappings / lle_dedup_strategy_mappings tables. The display lle history settings now persist through config save and load from lushrc.toml.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First, non-destructive phase of the CREG/config correctness overhaul (from a 64-agent audit). The central unified configuration system is a deliberate lush design pillar -- a single, discoverable source of truth that every surface (the
configbuiltin,display lle …,setopt, TOML) is meant to synchronize with. Several of those syncs were silently broken because keys were never registered. This makes them work; it removes nothing.Five commits, each verified:
config: resolve dotted registry keys from the config builtin—config get/setiterated only the legacyconfig_options[]array and never consulted the registry, so registry-only keys (completion.menu_shadow_ghost,chain_directories) reported "Unknown configuration key". Adds a registry fallback after the legacy lookup; purely additive.config: register the display hot-reload and pager keys—display lle hot-reload/display lle pagerwritedisplay.theme_hot_reloadanddisplay.lle.pager.*to the registry, and the sync hooks already mirror them, but the keys were unregistered so every write/sync was aCREG_ERROR_NOT_FOUNDno-op. Registering them makes thedisplay↔config sync work both directions.config: apply per-mode defaults to the runtime on init and mode change—apply_mode_defaultsseeded the registry but nothing synced it into the runtime struct on fresh install or on a mode switch, so mode-aware options didn't follow the active mode. Adds the missingsync_to_runtime.config: register completion.match_mode and threshold— these lived only in the legacy table, so theset_mode_default("completion.match_mode", …)calls failed silently and lush's curatedfuzzydefault never applied. Registers them with string↔enum sync; with commit 3, lush now resolves tofuzzyand posix/bash/zsh toprefix.config: add an lle registry section for history deduplication—display lle historywriteslle.enable_deduplication,lle.dedup_*to a section CREG didn't have. Adds thellesection so those settings persist and round-trip.Verification
meson test: 156/156, zero warnings (werror).config get/setround-trips registry-only keys;display lle hot-reload off/pager min-lines 12/history dedup offpersist toconfig saveand reload from TOML;completion.match_mode=fuzzyin lush andprefixin posix/bash/zsh, observable viaconfig getand$COMPLETION_MATCH_MODE.Not in this PR
The destructive/migration phases (remove 51 confirmed-dead/aspirational keys, migrate the remaining wired legacy-only keys into CREG, regenerate the embedded TOML, retire the legacy array) come next, with the aspirational-key removal list reviewed before anything is deleted.
🤖 Generated with Claude Code