feat(dispatch,llm): modules register their own default_bindings#70
Merged
Conversation
Modules now expose `pub const default_bindings: []const Binding`;
the dispatcher comptime-concatenates them into
`all_default_bindings`. The proxy's stdin matcher consults
user `config.keymap.bindings` first (user wins), then falls
back to `D.all_default_bindings` — so:
- Users who don't enable a module get none of its bindings.
- Users who enable a module get its bindings automatically
without editing `config.keymap.bindings`.
- Users who want to rebind a module key still can — list the
override in `Keymap.bindings` and the first-match scan picks
it before the module default.
LLM module's 14 default bindings (Alt+A/S/Shift+S/M/H/C/Shift+C +
Ctrl+Shift+X plus dual kitty-kbd encodings) moved from
`defaults.zig` into `atty.modules.llm.default_bindings`. defaults.zig
shrinks to the core, module-agnostic bindings (Right/End/Ctrl+F/
Ctrl+Tab/Ctrl+Right/Ctrl+Shift+I/Alt+i/Ctrl+Shift+D).
`renderHelp` walks both lists in the same order so the Alt+H
cheat-sheet still surfaces everything.
2 new dispatch tests cover: comptime-concat + skip non-declaring,
empty when no module declares.
`zig build test` (480 pass) + `zig fmt --check` clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
fentas
added a commit
that referenced
this pull request
May 17, 2026
docs: reflect recently-shipped features `docs/llm.md`: - New **Chat surfaces** section explaining Alt+C inline panel vs. Alt+Shift+C full overlay (same conversation ring, mutually exclusive cursor focus). - New **Keybindings** section listing every shipped LLM binding + Alt+H cheat-sheet pointer. - Configuration reference split into sections (Core / Chat surfaces / Persistence / Visual signals / Buffer sizes / Model struct) so the table doesn't overwhelm — and adds rows for `models`, `inline_chat_rows`, `overlay_open_policy`, `chat_persist_enabled`, `chat_persist_path`, `chat_persist_max_bytes`, `history_turns_max`, `max_turn_bytes`, `dialog_system_prompt`, `dialog_parse_retry_max`. - Documents the `Model` struct with the per-model `history_turns_max` trim knob. `docs/modules.md`: - Adds `default_bindings`, `onResize`, `isInlineChatActive`, `extraReserveRows` to the hook list. - New **default_bindings** section walks the module-owned keymap pattern (dispatcher concat + user-overrides-win precedence). - New **extraReserveRows** section documents the inline-panel reservation contract used by the LLM module's Alt+C panel.
3 tasks
fentas
added a commit
that referenced
this pull request
May 17, 2026
…dead (#72) Regression from #70: `default_bindings` sat at the top level of `src/modules/llm.zig`, but `config.modules` actually stores the RESULT of `llm.configure(.{...})` — i.e. the inner struct returned by the factory. The dispatcher's `@hasDecl(M, "default_bindings")` gate inspects the inner struct, so the top-level decl was invisible and every Alt+letter LLM binding silently missed. Fix: move the slice into the `configure()` return type alongside `name`, `config`, the action handlers, etc. — same scope `@hasDecl` walks for every other hook on the LLM module. Regression test (`allDefaultBindings: picks up bindings from configure()-style factory modules`) mirrors the real `pub fn configure(cfg) type` pattern via a `FactoryModule(tag)` fixture, so future module authors don't re-hit this trap. `zig build test` (484 pass) + `zig fmt --check` clean. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merged
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
Follow-up to PR #67 — modules now own their keybindings instead of having them centralized in
defaults.zig.How it works
pub const default_bindings: []const Binding = &.{ ... }.all_default_bindings.What changed
src/modules/llm.zig: gainspub const default_bindings = &.{ ... }— 14 entries (Alt+A/S/Shift+S/M/H/C/Shift+C/Ctrl+Shift+X + their kitty-kbd CSI-u siblings).src/defaults.zig: shrinks. The LLM block is replaced by a comment pointing to the module. Core, module-agnostic bindings (Right/End/Ctrl+F/Ctrl+Tab/Ctrl+Right/Ctrl+Shift+I/Alt+i/Ctrl+Shift+D) stay.src/dispatch.zig: newall_default_bindingsconst +allDefaultBindings()accessor.src/proxy.zig: matcher consults both lists;renderHelpwalks both for the Alt+H cheat-sheet.Behavioral consequences
atty.modules.llmfrom theirmodulestuple loses ALL the LLM bindings automatically — no manual cleanup ofKeymap.bindings.Keymap.bindingsfirst.Test plan
zig build test— 480/480 pass (2 new dispatch tests covering walker semantics + empty case)zig fmt --check— cleanmodulestuple in config.zig, rebuild — Alt+C no longer fires🤖 Generated with Claude Code