dotcli: add shortcut identifiers to dot kde save completion
dot kde save's tab-completion only ever enumerated schema-backed identifiers; kglobalshortcutsrc identifiers never showed up as candidates despite being a fully supported mechanism. Enumerate them live via kglobalaccel (allMainComponents/allActionsForComponent), printed as a separate block after the schema-backed one, degrading silently if the D-Bus session is unavailable.
This commit is contained in:
@@ -36,9 +36,16 @@ here.
|
|||||||
|
|
||||||
## Acceptance criteria
|
## Acceptance criteria
|
||||||
|
|
||||||
- [ ] `python3 kde.py complete` includes every currently-registered `kglobalshortcutsrc.<componentUnique>.<actionUnique>` identifier, sourced live via `allMainComponents`/`allActionsForComponent`
|
- [x] `python3 kde.py complete` includes every currently-registered `kglobalshortcutsrc.<componentUnique>.<actionUnique>` identifier, sourced live via `allMainComponents`/`allActionsForComponent`
|
||||||
- [ ] Schema-backed identifiers print first, followed by shortcut identifiers, as two distinct blocks — not interleaved into one merged sorted list
|
- [x] Schema-backed identifiers print first, followed by shortcut identifiers, as two distinct blocks — not interleaved into one merged sorted list
|
||||||
- [ ] Shortcut identifiers print plain, with no friendly-name description text
|
- [x] Shortcut identifiers print plain, with no friendly-name description text
|
||||||
- [ ] If the D-Bus walk raises `RuntimeError` or `OSError`, the shortcuts block is omitted, the schema block still prints normally, and nothing is written to stderr
|
- [x] If the D-Bus walk raises `RuntimeError` or `OSError`, the shortcuts block is omitted, the schema block still prints normally, and nothing is written to stderr
|
||||||
- [ ] Freeform identifiers remain unlisted by `cmd_complete` (unchanged, confirmed not a regression)
|
- [x] Freeform identifiers remain unlisted by `cmd_complete` (unchanged, confirmed not a regression)
|
||||||
- [ ] Verified manually against a live session — no new automated tests, consistent with the existing shortcuts-mechanism test carve-out (spec's testing decisions, 0005's Implementation Notes)
|
- [x] Verified manually against a live session — no new automated tests, consistent with the existing shortcuts-mechanism test carve-out (spec's testing decisions, 0005's Implementation Notes)
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
- `iter_shortcut_identifiers` (new, `commands/kde/kde.py`) walks `allMainComponents()` then `allActionsForComponent()` per component, yielding `kglobalshortcutsrc.<componentUnique>.<actionUnique>`. `cmd_complete` wraps that walk in `sorted(set(...))` and appends it as a second print loop after the existing schema-backed one, inside a `try/except (RuntimeError, OSError)` that falls back to an empty list on any failure — so a missing `busctl` or an unreachable D-Bus session degrades completion instead of breaking it.
|
||||||
|
- Manually verified both paths: live run on this machine prints 278 shortcut identifiers after 322 schema-backed ones; with `busctl` removed from `PATH` (simulating a non-KDE/minimal shell), `cmd_complete` still exits 0, prints only the 322 schema identifiers, and writes nothing to stderr.
|
||||||
|
- `/review-uncommitted`'s Standards pass flagged two judgement-call smells: (1) the D-Bus call/unpack idiom for `allActionsForComponent` was duplicated between the new function and `_resolve_shortcut_action_id`; (2) the silent `except` swallow had no comment explaining why. Fixed both: extracted a shared `_actions_for_component(component_unique)` helper used by both call sites, and added a comment on the `try` explaining that fish invokes this on every TAB press in shells that may lack a live KDE session, so a broken shortcuts source must never cost the already-printed schema candidates. Re-ran the full test suite (101/101 pass) and both manual checks after the fix.
|
||||||
|
- No automated tests added, per the task's own acceptance criterion and the shortcuts mechanism's existing test carve-out (0005's Implementation Notes: a live D-Bus session isn't practically substitutable without disproportionate mock infrastructure).
|
||||||
|
|||||||
@@ -224,9 +224,20 @@ def _kglobalaccel_call(method, signature, *tokens):
|
|||||||
return json.loads(result.stdout)["data"]
|
return json.loads(result.stdout)["data"]
|
||||||
|
|
||||||
|
|
||||||
def _resolve_shortcut_action_id(component_unique, action_unique):
|
def _actions_for_component(component_unique):
|
||||||
(actions,) = _kglobalaccel_call("allActionsForComponent", "as", 1, component_unique)
|
(actions,) = _kglobalaccel_call("allActionsForComponent", "as", 1, component_unique)
|
||||||
for action in actions:
|
return actions
|
||||||
|
|
||||||
|
|
||||||
|
def iter_shortcut_identifiers():
|
||||||
|
(components,) = _kglobalaccel_call("allMainComponents", None)
|
||||||
|
for component in components:
|
||||||
|
for action in _actions_for_component(component[0]):
|
||||||
|
yield f"kglobalshortcutsrc.{action[0]}.{action[1]}"
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_shortcut_action_id(component_unique, action_unique):
|
||||||
|
for action in _actions_for_component(component_unique):
|
||||||
if action[0] == component_unique and action[1] == action_unique:
|
if action[0] == component_unique and action[1] == action_unique:
|
||||||
return action
|
return action
|
||||||
|
|
||||||
@@ -391,6 +402,18 @@ def cmd_complete(schema_dir):
|
|||||||
kcfg_map = build_kcfg_map(schema_dir)
|
kcfg_map = build_kcfg_map(schema_dir)
|
||||||
for identifier in sorted(set(iter_schema_identifiers(kcfg_map))):
|
for identifier in sorted(set(iter_schema_identifiers(kcfg_map))):
|
||||||
print(identifier)
|
print(identifier)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Fish's completion runs this on every TAB press, in shells that may have no
|
||||||
|
# live KDE session (or no busctl at all) -- a broken shortcuts source must
|
||||||
|
# never cost the schema-backed candidates already printed above.
|
||||||
|
shortcut_identifiers = sorted(set(iter_shortcut_identifiers()))
|
||||||
|
except (RuntimeError, OSError):
|
||||||
|
shortcut_identifiers = []
|
||||||
|
|
||||||
|
for identifier in shortcut_identifiers:
|
||||||
|
print(identifier)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user