Introduces the dot kde subcommand family (fish dispatcher plus a Python helper under commands/kde/), a flat identifier=value manifest, and dot kde save in both its explicit-identifier and no-argument refresh modes. Settings resolve to KDE's KConfigXT schema-backed mechanism via a (rcfile -> [kcfg files]) mapping table auto-derived by scanning the system schema directory (overridable via DOT_KDE_KCFG_DIR), plus a hand-maintained exceptions list for schemas that only declare their target rc file at runtime. Also wires tab-completion for dot kde save identifiers, sourced live from that same mapping table.
5.5 KiB
spec, blocked-by
| spec | blocked-by |
|---|---|
| dot-kde | 0000-nested-subcommand-discovery |
What to build
Stand up dot kde itself: the fish dispatcher plus its Python helper,
living together under commands/kde/ per the nested-subcommand layout
from the prior task. Establish the manifest file (flat text file directly
under ~/.config/dot/, one identifier=value line each, split on the
first = only; identifier split on the first two .s into
file.group.key, leaving the key free to contain further dots or spaces).
Implement the KConfigXT schema-backed mechanism: reads and writes go
through kreadconfig6/kwriteconfig6, and the "default" value for a
setting comes from its .kcfg schema. Build the (rcfile → [kcfg files])
mapping table by scanning the system's KConfigXT schema directory for
files that statically declare their target rc file
(<kcfgfile name="...">), plus a small hand-maintained list for the
exceptions that only declare their target file at runtime
(<kcfgfile arg="true"> — kwin.kcfg is a known example). The schema
directory location must be overridable (e.g. via an environment variable),
defaulting to the real system path, so tests can point it at a fixture
directory of synthetic .kcfg files instead.
Structure identifier resolution as a dispatchable decision (rc file is
kglobalshortcutsrc → shortcuts; else resolves via the mapping table →
schema-backed; else → freeform) even though only the schema-backed branch
is implemented yet — later tasks add the other two branches without
restructuring this.
Implement dot kde save for schema-backed settings, in both modes:
run with no arguments, refresh every already-declared manifest entry's
value from the live system; run with an explicit identifier, read its
current live value and add it to the manifest as a new declared entry.
Add dot kde help and dot kde save help, following the project's
check-for-help-before-argparse convention at each dispatch level.
Add README rows for dot kde help, dot kde save <identifier>, and
dot kde save (no arguments).
Acceptance criteria
dot kdeanddot kde saveare discoverable viadot helpand dispatch correctly- Manifest parsing splits correctly on the first
=(values may contain=) and the first two.s of the identifier (keys may contain dots/spaces) - The
(rcfile → [kcfg files])mapping table is derived by scanning a schema directory for<kcfgfile name="...">, plus the hand-maintained exceptions list forarg="true">schemas - The schema directory is overridable via an environment variable, defaulting to the real system path
dot kde save <identifier>reads the current live value viakreadconfig6and adds a new declared entry to the manifestdot kde savewith no arguments refreshes every already-declared manifest entry's stored value from the live system, leaving undeclared settings untoucheddot kde helpanddot kde save helpprint usage without touching the manifest or invokingkreadconfig6/kwriteconfig6- Tests run against a scratch
$HOMEand a fixture.kcfgschema directory, exercising manifest read/write, identifier parsing, and mapping-table-driven default lookup, per the project's scratch-$HOME-plus-fishtapeconvention - README has rows for
dot kde help,dot kde save <identifier>, anddot kde save
Implementation Notes
- File layout:
commands/kde/kde.fish(thin dispatcher: help-before-dispatch at thedot kdelevel, then hands off to the Python helper) pluscommands/kde/kde.py(manifest parsing, mapping-table derivation, mechanism resolution,kreadconfig6invocation, andsave's own help-before-work check). - Manifest location:
~/.config/dot/kde-manifest, a flat file directly under~/.config/dot/as specified. - Mechanism dispatch (
resolve_mechanism) implements all three branches described in the parent spec (shortcuts / schema / freeform) even though onlyschemais wired to real behavior;shortcutsandfreeformboth currently raise a clear "not yet supported" error fromsave_one, so later tasks can fill them in without restructuring the dispatch. - Test fixtures added under
tests/fixtures/kcfg/:testrc.kcfg(a plain<kcfgfile name="...">schema, including an entry whose inikey=differs from its schemaname=, and one entry whose key contains dots and spaces),kwin.kcfg(anarg="true"schema resolved only via the hand-maintained exceptions list), andunmapped.kcfg(anarg="true"schema absent from that list, proving it's never guessed at from its own filename). - Per the project's testing convention,
kreadconfig6is never mocked for the tests exercising actualsavebehavior — it runs for real against fixture rc files under a scratch$HOME. It's faked (via a$PATH-prepended logging stub) only for the two tests asserting thatdot kde help/dot kde save helpnever invoke it. - Applied two small cleanups surfaced by
/review-uncommitted's Standards pass before closing out: extracted a shared_parse_kcfghelper (was duplicated betweenbuild_kcfg_mapandfind_schema_default), and introduced aSetting = namedtuple("Setting", ["file", "group", "key"])to stop threading those three strings as separate parameters acrossresolve_mechanism/find_schema_default/read_live_value/save_one. - The Spec pass caught that the
unmapped.kcfgfixture was created but never actually exercised by a test; added a case assertingdot kde save unmapped.Whatever.Settingresolves to freeform rather than schema-backed.