Skip to content

Let local bindings override global ones and sort the menu by key - #67

Merged
844196 merged 1 commit into
mainfrom
844196/main/local-bindings-precedence-and-sort
Sep 3, 2026
Merged

Let local bindings override global ones and sort the menu by key#67
844196 merged 1 commit into
mainfrom
844196/main/local-bindings-precedence-and-sort

Conversation

@844196

@844196 844196 commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

globalBindings.concat(localBindings) conflated two unrelated concerns: which definition won when global and local bindings shared a key, and what order the menu drew rows in.

  • Conflict resolution: local bindings now shadow global ones sharing a key, whole-entry — a group and a command never partially merge, and a group's own nested bindings never cross the global/local boundary.
  • Display order: menu rows sort by key (ICU collation, fixed to en so it doesn't shift with the user's LANG; numeric so f2 sorts before f10 regardless of digit width; uppercase before lowercase), independent of declaration order or global/local origin, at every nesting level — not just the merged top level.
  • Duplicate keys: a duplicated key now collapses to a single row before it reaches the menu, matching what a keypress already resolved to (main.ts's find always resolved to the first match; previously the menu still showed the unreachable second row).

Breaking changes

  • A local binding used to lose to a global one sharing the same key; it now wins.
  • Menu rows used to draw in declaration order; they now sort by key.

@844196
844196 requested a balanced review from Copilot September 3, 2026 16:25
@844196 844196 self-assigned this Sep 3, 2026

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.

🟡 Changes recommended

The specified uppercase-before-lowercase ordering lacks acceptance-test coverage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Separates binding conflict resolution from menu ordering.

Changes:

  • Local bindings override conflicting global bindings.
  • Duplicate keys collapse to the first reachable entry.
  • Rows sort recursively using fixed-locale natural key ordering.
File summaries
File Description
src/run.ts Adds merging, deduplication, and recursive sorting.
e2e/tests/04_config.bats Tests local override behavior.
e2e/tests/07_render.bats Tests deduplication and sorting.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/run.ts
844196 added a commit that referenced this pull request Sep 3, 2026
Copilot's review of #67 flagged that `caseFirst: 'upper'` (src/run.ts's
keyCollator) had no e2e coverage: nothing would catch a regression that
dropped it or changed the tie-break direction.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@844196
844196 requested a balanced review from Copilot September 3, 2026 16:28

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.

🟡 Changes recommended

The tests do not cover preservation and ordering of bindings across nonempty global and local sources.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

e2e/tests/04_config.bats:177

  • No global-only key is exercised while the local file is nonempty: every global key is shadowed, so an implementation that drops the global list entirely would still pass. Add a unique global binding and assert that both sources contribute.
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread e2e/tests/07_render.bats Outdated
844196 added a commit that referenced this pull request Sep 3, 2026
Copilot's review of #67 flagged that "local bindings override global ones
with the same key" only used keys that were either shadowed by local or
local-only: an implementation that dropped the global list entirely (rather
than merging it) would still have passed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@844196
844196 requested a balanced review from Copilot September 3, 2026 16:31

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.

🟡 Changes recommended

Collation-equivalent distinct keys can still retain declaration-dependent ordering.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread src/run.ts Outdated
844196 added a commit that referenced this pull request Sep 3, 2026
…stic

Copilot's review of #67 caught that `Intl.Collator`'s `numeric` option
compares distinct keys like `f2` and `f02` as equal, and `toSorted` is
stable — so two such keys kept whatever relative order they happened to
arrive in (merge order, declaration order), contradicting the promise that
display order doesn't depend on origin.

Also covers a second gap the same review round flagged: the
"regardless of declaration order" render test only ever used a single
(global) source, so it couldn't catch an implementation that sorted each
source separately before concatenating them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@844196
844196 requested a balanced review from Copilot September 3, 2026 16:36

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.

🟡 Changes recommended

ICU numeric collation cannot satisfy the stated unlimited digit-width ordering guarantee.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread src/run.ts
844196 added a commit that referenced this pull request Sep 3, 2026
Copilot's review of #67 pointed out ICU chunks numeric collation past 254
significant digits, so "no width limit" overclaimed what `Intl.Collator`
actually guarantees. A key name that long is not a real scenario for a
keybinding menu, so this narrows the comment rather than hand-rolling an
arbitrary-precision comparator.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@844196
844196 requested a balanced review from Copilot September 3, 2026 16:40

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.

🟢 Approval recommended

The implementation matches the described behavior and has focused end-to-end coverage.

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

`globalBindings.concat(localBindings)` conflated two unrelated concerns:
which definition won when global and local shared a key (main.ts's `find`
always resolved to the first match, so global won), and what order the
menu drew rows in (declaration order, since nothing reordered the array).

Local bindings now shadow global ones sharing a key, whole-entry — a group
and a command never partially merge, and a group's own nested `bindings`
never cross the global/local boundary. Menu rows sort by key with a fixed
locale (natural for digit runs, so f2 comes before f10; uppercase before
lowercase; an exact-string tie-break where the collation itself calls two
distinct keys equal, e.g. f2 vs f02), independent of declaration order or
global/local origin, at every nesting level. A duplicate key now collapses
to a single row before it reaches the menu, matching what a keypress
already resolved to.

BREAKING CHANGE: a local binding used to lose to a global one sharing the
same key; it now wins. Menu rows used to draw in declaration order; they now
sort by key.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@844196
844196 force-pushed the 844196/main/local-bindings-precedence-and-sort branch from 14f4dc1 to 27018bd Compare September 3, 2026 16:43
@844196
844196 merged commit 9ada7d6 into main Sep 3, 2026
3 checks passed
@844196
844196 deleted the 844196/main/local-bindings-precedence-and-sort branch September 3, 2026 16:45
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