Skip to content

Give every native arrow control the same saved key preference - #207

Merged
trissim merged 1 commit into
mainfrom
work/toad-keymap--P917--arrow-routing
Oct 29, 2026
Merged

trissim merged 1 commit into
mainfrom
work/toad-keymap--P917--arrow-routing

Conversation

@trissim

@trissim trissim commented Oct 29, 2026

Copy link
Copy Markdown

Summary

AI-generated by toad-keymap (OpenAI Codex), for maintainer-directed P917 / OpenHCSDev/toad#1318. One core issue, paired with that ToAD continuation.

  • Four arrow preferences replace separate per-widget input identities.
  • Five production files changed; no widget-specific hjkl roster, action body migration, automated test, fake app, dependency install or provider submission.
  • Before: native TextArea and Toad CursorUpAction were separate saved identities; DataTable/Tree/List/Menu raw arrows had no editable identity.
  • After: original declared arrow identity is decoded once in Binding.make_bindings, retained independently of configured key spelling, and projected into the actual mode by Binding/BindingsMap. Each control retains its own native action/state/availability.

Native class structure

Before: KeyInvocation → MethodBinding / CommandBinding; raw Binding.invocations() was empty. F1 saw only opted-in declarations. Input consumption and list search could swallow printable mappings.

After: DeclaredKey owns original input identity. Its undecoded boundary member decodes a declaration once; NavigationKey composes DeclaredKey and KeyInvocation. UpKey/DownKey/LeftKey/RightKey declare only their native Keys member; the family registry derives from subclass declarations. Binding keeps this original identity when configured spelling changes. Native command implementation remains on MethodBinding, CommandBinding or raw Binding.

DOMNode.binding_defaults and instance binding_map both use BindingsMap.project. Existing bindings and native callable declarations therefore reach both catalog and dispatch. No application mirror of Textual's controls.

Deleted competing behavior

BindingsMap.apply_keymap no longer mutates its input map while walking it or drops all but the first native alternative sharing an invocation. It builds the overlay once, preserves distinct native alternatives and deduplicates equal aliases. Empty override unbinds; absent override preserves defaults; Reset removes the override in ToAD.

Configured printable arrow aliases are dispatched on the existing modal binding chain before type-to-search. MethodBinding forwards the ORIGINAL decoded event once to its existing editor handler; it does not invent or replay an arrow. The original EditingMode still owns pending operands, native geometry, selection and history.

Global arrow preferences stay visible in F1's previous-focus filter, including from an Input with no vertical navigation. Other commands still derive visibility from enabled focused IDs.

Actual original failure

Installed ToAD8e8c962e7 / Textuale7a48c59, ordinary st/Xvfb with retained real saved sessions and copied user configuration. Prompt k/j worked; sidebar required a second same-title preference. Even setting both Up identities left F1's DataTable k inert while Up moved it (screens35–37). Actual Normal o was also inert; real Vim is separate root-owned work, not patched one key at a time here.

Retained evidence: /home/ts/.cache/agent-scratch/toad-keymap/p917-installed-reset-history/current-remap/RESULT.md.

Source evidence

Before map:308ToAD+256Textual modules,2557classes,1987relevant syntactic sites,45arrow candidates,0parse omissions. Candidate count includes non-binding literals; retained map reports syntax, not dynamic resolution. p917-arrow-map.json/.log in owner scratch.

Initial source check compiled8paired modules and imported the actual catalog:113invocations, exactly one each Cursor up/down/left/right, owned by textual.keys.UpKey/DownKey/LeftKey/RightKey. That is source/import evidence, not physical corrected-build acceptance. Physical corrected-source controls are still in progress at this checkpoint. No author pytest/full suite/ratchet run.

Stored preferences / install requirement

Arrow invocation identities change. Merger must convert old per-widget arrow overrides ONCE before installing, retaining original config and refusing conflicting old choices for the same arrow+mode. This PR intentionally adds no old-name aliases, compatibility readers or load-time converters. Native old defaults determine arrow identity; no hand-kept widget roster. Original user settings are not changed by the worker.

Remaining acceptance

Actual F1 save/reopen h/j/k/l across multiline prompt, Input/MaskedInput, sidebar/tree/list/table/menu/modal, genuine history/draft edges, Reset and mode isolation. Installed bytes and corrected-source overlays remain distinct. No claim of full K2–K7 or Vim completion.

Assumed: raw native arrow bindings retain their existing state/action contracts; dynamic string action resolution is exercised through the actual application, not inferred from AST.

one Up setting
table, tree and prompt keep their own legs
no more buying k separately for each widget

Copilot AI balanced review requested due to automatic review settings October 29, 2026 05:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@trissim
trissim merged commit 79a8a6d into main Oct 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants