Repository navigation
Allow space as a bindable key in custom keybindings - #3333
Conversation
Lock the settings-file and schema behavior requested in issue 1711 before changing the parser. The Swift test captures the current space-key gap by requiring kVK_Space resolution and a stable config round trip; the web test validates the settings schema artifact instead of checking schema source text. Constraint: Repo policy says not to run tests locally; this commit is intentionally test-only and expected to fail before the parser/schema fix.\nConfidence: high\nScope-risk: narrow\nTested: Not run locally; regression tests added as the red commit.\nNot-tested: Local XCTest and Bun test execution.
The settings parser now stores Space as the canonical key token, records physical Space key events as kVK_Space, resolves Space for matching and Carbon registration, and serializes back to settings.json as space. The settings schema now validates shortcut strokes against supported parser tokens and includes space, Space, <space>, and <Space>. Constraint: Direct xcodebuild is forbidden for this branch; local test runners are also disallowed by repo policy.\nRejected: Keep storing Space as a literal blank string | it round-trips poorly and cannot resolve to a stable key code.\nConfidence: high\nScope-risk: narrow\nDirective: Keep shortcut parser tokens, key-code resolution, schema shortcutStroke, and docs/examples in sync when adding future named keys.\nTested: git diff --check; Node JSON parse for schema and xcstrings; Node regex smoke for space aliases and unknown key rejection.\nNot-tested: Local XCTest/Bun test execution; final app behavior pending required tagged reload launch.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds first-class Space key support for shortcuts: localization entry, config parsing and normalization for "space" (and aliases), keycode mapping/matching (kVK_Space = 49), UI display/equivalents, JSON schema tightening for shortcut strokes, tests, and project wiring for the new tests. ChangesSpace Key Shortcut Support
Sequence DiagramsequenceDiagram
participant User
participant Parser as Config Parser
participant Store as StoredShortcut
participant Event as Keyboard Event
participant UI as UI Display
User->>Parser: Provide "cmd+shift+space"
Parser->>Parser: split on '+', trim per-token
Parser->>Parser: normalize " " / "<space>" / "spacebar" → "space"
Parser->>Store: create StoredShortcut(key: "space", modifiers: [cmd,shift])
Store->>Store: allow empty modifiers when key == "space"
Event->>Store: space pressed (keycode 49) with cmd+shift
Store->>Store: resolve "space" → keycode 49, compare modifiers
Store-->>Event: match true
UI->>Store: request display string
Store-->>UI: "Space" (localized)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
web/tests/settings-schema.test.ts (1)
149-154: ⚡ Quick winExpand Space alias coverage to match the documented accepted forms.
The current cases don’t cover
<Space>,spacebar, and literal-space bindings, which are part of the intended alias set for this PR.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/tests/settings-schema.test.ts` around lines 149 - 154, Update the "accepts Space key names in shortcut bindings" test to cover all documented Space aliases by adding additional expects that call validatesSettings(settingsWithBinding(...)) for "<Space>", "spacebar", and a literal space character binding (e.g., "cmd+shift+<Space>" or " " / ["ctrl+b", " "]) so the test uses validatesSettings and settingsWithBinding to assert true for these forms in addition to the existing cases.cmuxTests/WorkspaceUnitTests.swift (1)
680-690: ⚡ Quick winAdd assertions for the remaining documented Space aliases.
This test covers
Space,<space>, and literal-space, but it currently missesspacebarand<Space>which are explicitly part of the accepted alias set. Adding them here would close the regression gap.Suggested test additions
XCTAssertEqual(StoredShortcut.parseConfig("cmd+shift+Space")?.configIdentifier, "cmd+shift+space") XCTAssertEqual(StoredShortcut.parseConfig("cmd+shift+<space>")?.configIdentifier, "cmd+shift+space") + XCTAssertEqual(StoredShortcut.parseConfig("cmd+shift+<Space>")?.configIdentifier, "cmd+shift+space") + XCTAssertEqual(StoredShortcut.parseConfig("cmd+shift+spacebar")?.configIdentifier, "cmd+shift+space") XCTAssertEqual(StoredShortcut.parseConfig("cmd+shift+ ")?.configIdentifier, "cmd+shift+space")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmuxTests/WorkspaceUnitTests.swift` around lines 680 - 690, The tests around StoredShortcut.parseConfig are missing assertions for the documented aliases "spacebar" and the case-variant "<Space>"; update WorkspaceUnitTests.swift to add checks (similar to the existing ones) that StoredShortcut.parseConfig("spacebar") and StoredShortcut.parseConfig("<Space>") unwrap successfully, have parsed .key == "space", .firstStroke.resolvedKeyCode() == spaceKeyCode, and that configIdentifier normalizes to "space" (and for prefixed forms e.g. "cmd+shift+space" when using those aliases), using the same assertion style as the existing StoredShortcut.parseConfig tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/data/cmux-settings.schema.json`:
- Around line 620-624: The JSON schema's "shortcutStroke" pattern only allows
lowercase media tokens and rejects camelCase aliases like
playPause/media.playPause; update the "pattern" for "shortcutStroke" in
cmux-settings.schema.json to also accept camelCase variants (e.g.,
playPause|media\.playPause, nextTrack|media\.next,
previousTrack|previousTrack|media\.previous|media\.previousTrack,
volumeUp|media\.volumeUp, volumeDown|media\.volumeDown,
brightnessUp|media\.brightnessUp, brightnessDown|media\.brightnessDown,
mediaMute|media\.mute, etc.) or otherwise make the media-key alternatives
case-insensitive so the runtime-accepted aliases (playPause, media.playPause,
nextTrack, etc.) validate successfully.
In `@web/tests/settings-schema.test.ts`:
- Around line 21-136: The test currently uses a handcrafted validator (functions
resolveRef, matchesType, validateSchemaValue, validatesSettings) that only
implements a subset of JSON Schema; replace it by invoking a standards-compliant
JSON Schema runtime validator (e.g., Ajv with draft-2020-12) to validate
candidate settings against rootSchema: remove or stop calling
validateSchemaValue/validatesSettings and instead instantiate Ajv, compile
rootSchema (or add $defs), and run ajv.validate(compiledSchema, candidate) in
the tests so assertions use the ajv result; ensure any schema $refs/$defs in
rootSchema are preserved when compiling and update tests to assert on ajv.errors
for failure cases.
---
Nitpick comments:
In `@cmuxTests/WorkspaceUnitTests.swift`:
- Around line 680-690: The tests around StoredShortcut.parseConfig are missing
assertions for the documented aliases "spacebar" and the case-variant "<Space>";
update WorkspaceUnitTests.swift to add checks (similar to the existing ones)
that StoredShortcut.parseConfig("spacebar") and
StoredShortcut.parseConfig("<Space>") unwrap successfully, have parsed .key ==
"space", .firstStroke.resolvedKeyCode() == spaceKeyCode, and that
configIdentifier normalizes to "space" (and for prefixed forms e.g.
"cmd+shift+space" when using those aliases), using the same assertion style as
the existing StoredShortcut.parseConfig tests.
In `@web/tests/settings-schema.test.ts`:
- Around line 149-154: Update the "accepts Space key names in shortcut bindings"
test to cover all documented Space aliases by adding additional expects that
call validatesSettings(settingsWithBinding(...)) for "<Space>", "spacebar", and
a literal space character binding (e.g., "cmd+shift+<Space>" or " " / ["ctrl+b",
" "]) so the test uses validatesSettings and settingsWithBinding to assert true
for these forms in addition to the existing cases.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6be18ece-5eab-4371-8c15-62a401a07d6b
📒 Files selected for processing (5)
Resources/Localizable.xcstringsSources/KeyboardShortcutSettings.swiftcmuxTests/WorkspaceUnitTests.swiftweb/data/cmux-settings.schema.jsonweb/tests/settings-schema.test.ts
Greptile SummaryThis PR adds first-class Space key support by canonicalizing it to the token Confidence Score: 5/5Safe to merge; normal typing and all modifier shortcuts are unaffected, and the Space bypass path is correctly gated behind the settings/cmux.json checks. The fast-path bypass logic preserves existing behaviour for all keys except explicitly configured bare Space shortcuts. The settings cache uses queue:.main (thread-safe), the modifier-or-Space invariant is enforced at both parse and schema layers, and regression tests cover parsing, kVK_Space resolution, settings round-trip, and routing. Both findings are non-critical edge cases with no effect under normal use. Sources/App/ShortcutBareStartRouting.swift — the special-key branch in bareShortcutFastPathKey is dead code worth pruning. Sources/KeyboardShortcutSettings.swift — the isUnboundConfigToken change silently alters behaviour for mixed-whitespace tokens. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[NSEvent keyDown arrives] --> B{normalizedFlags empty AND no active chord prefix?}
B -- No --> F[Continue shortcut dispatch]
B -- Yes --> C{bareShortcutFastPathKey}
C -- nil: regular letter/symbol --> G[Bypass - normal typing]
C -- space keyCode 49 --> D{KeyboardShortcutBareStartCache hasConfiguredBareShortcutStart?}
C -- special key arrow or F-key --> D
D -- Yes in settings cache --> F
D -- No cache miss --> E{configuredCmuxShortcutActions bareShortcutStartKey match?}
E -- Yes --> F
E -- No --> G
Reviews (4): Last reviewed commit: "Keep bare shortcut cache invalidation on..." | Re-trigger Greptile |
Merged origin/main into issue-1711-space-modifier and resolved the schema conflict by keeping main's cmux-settings.schema.json compatibility ref while moving the PR's space-key shortcut validation into the canonical cmux.schema.json. The resolution also preserves main's shortcut unbinding tokens instead of narrowing the schema back to shortcut-only strings. Constraint: main moved settings schema validation into web/data/cmux.schema.json Rejected: Restore the full cmux-settings.schema.json body | would undo the main-branch schema migration Confidence: high Scope-risk: moderate Directive: Keep shortcut syntax validation in cmux.schema.json while cmux-settings.schema.json remains a compatibility ref Tested: jq empty web/data/cmux-settings.schema.json web/data/cmux.schema.json; node shortcut schema pattern probe; git diff --check; ./scripts/reload.sh --tag issue-1711-space-modifier --launch Not-tested: Local unit/e2e test suites per repository testing policy
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmuxTests/WorkspaceUnitTests.swift`:
- Around line 618-682: The new tests testShortcutConfigParsingRoundTripsSpaceKey
and testSettingsFileStoreParsesSpaceShortcutBinding caused
WorkspaceUnitTests.swift to exceed the file-length budget; move those two
methods into a new test file named KeyboardShortcutSpaceKeyTests.swift, wrapping
them in the same test target imports and XCTestCase subclass used by the
project, then delete the corresponding methods from WorkspaceUnitTests.swift;
ensure the new file references existing helpers (e.g., makeTemporaryDirectory,
writeSettingsFile, StoredShortcut, KeyboardShortcutSettingsFileStore) rather
than redefining them and run the test suite to verify compilation and coverage
remain unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: eee503cb-ccf5-49cd-9384-4136f711dde6
📒 Files selected for processing (3)
Resources/Localizable.xcstringsSources/KeyboardShortcutSettings.swiftcmuxTests/WorkspaceUnitTests.swift
✅ Files skipped from review due to trivial changes (2)
- Resources/Localizable.xcstrings
- Sources/KeyboardShortcutSettings.swift
Addressed CI and review feedback after bringing the branch current with main. The Space shortcut tests now live in a focused test file so WorkspaceUnitTests stays under the line budget, the parser no longer relies on allSatisfy's empty-collection behavior, and the canonical cmux schema accepts the same mixed-case Space/media aliases that the runtime parser accepts. The brittle web schema test was removed instead of adding a new validator dependency; it had been testing checked-in schema metadata with a partial handcrafted validator and failed once cmux-settings.schema.json became a compatibility ref to cmux.schema.json. Constraint: Repository policy forbids local test-suite runs and new dependencies were not explicitly requested Rejected: Add Ajv just for the deleted schema test | would add a new dependency for metadata-only coverage Confidence: high Scope-risk: narrow Directive: Keep shortcut schema aliases aligned with ShortcutStroke.parseConfig when adding future named keys Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv; jq empty web/data/cmux.schema.json web/data/cmux-settings.schema.json; node shortcut schema pattern probe; git diff --check; ./scripts/reload.sh --tag issue-1711-space-modifier --launch Not-tested: Local test suites per repository testing policy
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Sources/KeyboardShortcutSettings.swift (1)
2165-2197:⚠️ Potential issue | 🟠 Major | ⚡ Quick winLiteral-space single-stroke bindings still parse as unbound.
StoredShortcut.parseConfig(" ")never reaches the new"space"normalization becauseisUnboundConfigToken(_:)trims whitespace first and short-circuits to.unbound. So the literal-space alias only works in forms likecmd+, not as a single-stroke" "binding fromsettings.json. That misses one of the stated compatibility paths for this PR.Suggested fix
private static func isUnboundConfigToken(_ rawValue: String) -> Bool { - let normalized = rawValue.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() - return normalized.isEmpty || normalized == "none" || normalized == "clear" || normalized == "unbound" + if rawValue.isEmpty { return true } + let normalized = rawValue.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() + return normalized == "none" || normalized == "clear" || normalized == "unbound" }That also makes it worth adding a regression assertion for
StoredShortcut.parseConfig(" ")?.configIdentifier == "space".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Sources/KeyboardShortcutSettings.swift` around lines 2165 - 2197, The single-space string is being trimmed away by isUnboundConfigToken(_:) so parseConfig(_ rawValue: String) should special-case a literal single-space before calling isUnboundConfigToken; update parseConfig(_:) to check if rawValue == " " (or the exact space character you're targeting) and map it to parseConfig(strokes: ["space"]) (or otherwise construct StoredShortcut with a stroke whose key normalizes to "space"), leaving isUnboundConfigToken unchanged; add a regression test asserting StoredShortcut.parseConfig(" ")?.configIdentifier == "space" and reference parseConfig(_:), isUnboundConfigToken(_:), and configIdentifier in your changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/data/cmux.schema.json`:
- Around line 662-665: The description for the schema branch referenced by
"$ref": "#/$defs/shortcutStroke" still mentions unbind tokens ("Use an empty
string, none, clear, or unbound to unbind.") which are only valid in the
unboundShortcutBinding oneOf branch; update the description for shortcutStroke
to remove any mention of empty string/none/clear/unbound and instead document
only valid stroke values (e.g., example like "Single-stroke shortcut, for
example cmd+n.") so consumers/IDEs aren't misled; locate the JSON entry with
"$ref": "#/$defs/shortcutStroke" and edit its "description" accordingly.
---
Outside diff comments:
In `@Sources/KeyboardShortcutSettings.swift`:
- Around line 2165-2197: The single-space string is being trimmed away by
isUnboundConfigToken(_:) so parseConfig(_ rawValue: String) should special-case
a literal single-space before calling isUnboundConfigToken; update
parseConfig(_:) to check if rawValue == " " (or the exact space character you're
targeting) and map it to parseConfig(strokes: ["space"]) (or otherwise construct
StoredShortcut with a stroke whose key normalizes to "space"), leaving
isUnboundConfigToken unchanged; add a regression test asserting
StoredShortcut.parseConfig(" ")?.configIdentifier == "space" and reference
parseConfig(_:), isUnboundConfigToken(_:), and configIdentifier in your changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1f74eaf5-94c1-4706-a30e-ead00ddf0f84
📒 Files selected for processing (4)
GhosttyTabs.xcodeproj/project.pbxprojSources/KeyboardShortcutSettings.swiftcmuxTests/KeyboardShortcutSpaceKeyTests.swiftweb/data/cmux.schema.json
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5ccdc94. Configure here.
Fix isUnboundConfigToken to treat only a truly empty string as unbound; whitespace-only strings (including a bare literal space) now reach the parser and resolve to kVK_Space via parseConfigKeyToken. Add <Space> and spacebar alias assertions plus a bare-space regression test. Fix the shortcutStroke oneOf branch description which incorrectly mentioned unbind tokens. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Sources/KeyboardShortcutSettings.swift (1)
2181-2181: 💤 Low valueConsider adding a comment explaining the space modifier exemption.
Bare keys without modifiers are normally rejected, but
spaceis special-cased here. A brief inline comment would help future maintainers understand this is intentional.📝 Suggested comment
- guard !firstStroke.modifierFlags.isEmpty || firstStroke.key == "space" else { return nil } + // Space is allowed without modifiers (e.g., for modal/leader-key workflows) + guard !firstStroke.modifierFlags.isEmpty || firstStroke.key == "space" else { return nil }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Sources/KeyboardShortcutSettings.swift` at line 2181, The guard that rejects bare keys (guard !firstStroke.modifierFlags.isEmpty || firstStroke.key == "space" else { return nil }) needs a brief inline comment explaining why "space" is allowed as an exception; update the line around the guard in KeyboardShortcutSettings (referencing firstStroke.modifierFlags and firstStroke.key) to add a short comment that states that space is intentionally permitted as a standalone shortcut (e.g., used for quick toggles or accessibility) so future maintainers understand this special-case behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@Sources/KeyboardShortcutSettings.swift`:
- Line 2181: The guard that rejects bare keys (guard
!firstStroke.modifierFlags.isEmpty || firstStroke.key == "space" else { return
nil }) needs a brief inline comment explaining why "space" is allowed as an
exception; update the line around the guard in KeyboardShortcutSettings
(referencing firstStroke.modifierFlags and firstStroke.key) to add a short
comment that states that space is intentionally permitted as a standalone
shortcut (e.g., used for quick toggles or accessibility) so future maintainers
understand this special-case behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b8e2d16c-9980-4b05-bd70-03475a4ec9ab
📒 Files selected for processing (3)
Sources/KeyboardShortcutSettings.swiftcmuxTests/KeyboardShortcutSpaceKeyTests.swiftweb/data/cmux.schema.json
🚧 Files skipped from review as they are similar to previous changes (2)
- cmuxTests/KeyboardShortcutSpaceKeyTests.swift
- web/data/cmux.schema.json
The app records and serializes unshifted punctuation keys as literal one-character shortcut tokens, so schema validation must accept those same canonical values instead of only their word aliases. Constraint: cmux.json consumers validate against web/data/cmux.schema.json while app-generated defaults use configIdentifier strings like cmd+, cmd+[ and cmd+=. Rejected: Change the renderer to word aliases | would churn existing documented/default shortcut strings and diverge from the Swift parser's accepted literal tokens. Confidence: high Scope-risk: narrow Tested: node JSON parse and shortcutStroke regex smoke check for punctuation aliases/media/space cases Tested: git diff --check Tested: ./scripts/reload.sh --tag shortcut-schema-punctuation
|
Pushed
Verification:
CI/checks are running on the new commit. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/data/cmux.schema.json`:
- Around line 663-673: The schema currently reuses $defs.shortcutStroke for both
standalone bindings and every chord position, which allows first/only strokes
like "n" or "left" to validate but later be rejected by
StoredShortcut.parseConfig; add a new stricter definition (e.g.
$defs.shortcutFirstStroke) that requires either at least one modifier or the key
"space" (match the same constraints used by StoredShortcut.parseConfig), update
places where a standalone binding or the first element of a chord is expected to
reference $defs.shortcutFirstStroke instead of $defs.shortcutStroke, and keep
$defs.shortcutStroke for the second chord element so two-part chords still
accept bare keys for the second stroke.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
The runtime only accepts a first or standalone shortcut stroke when it has a modifier, except for bare Space. The schema now mirrors that contract while preserving bare keys for the second stroke of a chord. Constraint: JSON Schema validation should reject configs that StoredShortcut.parseConfig rejects at runtime. Rejected: Reuse shortcutStroke everywhere | it over-accepts bare first strokes such as n and left. Confidence: high Scope-risk: narrow Tested: node JSON parse and shortcut binding smoke check for first-stroke, chord, punctuation, Space, and invalid bare-key cases Tested: git diff --check Tested: ./scripts/reload.sh --tag shortcut-schema-punctuation
|
Follow-up pushed in
Additional verification:
|
|
Additional validation after the schema follow-up:
Latest PR checks are green, including CircleCI macOS debug/release/unit, web typecheck, web DB migrations, Vercel previews, Cursor Bugbot, and CodeRabbit. |
The shortcut parser now accepts Space without modifiers, including as a chord prefix, so the AppDelegate plain-key fast path has to distinguish ordinary typing from configured bare shortcut starts. Cache the configured bare starts from shortcut settings and include cmux.json action shortcuts before returning early, preserving the hot typing path when Space is not configured. Constraint: Space is typing-latency-sensitive and must stay on the fast pass-through path unless a configured bare shortcut can match. Rejected: Disallow bare Space chord prefixes | the parser and schema already support Space as a bindable key, and routing can support it narrowly. Confidence: high Scope-risk: narrow Tested: ./scripts/reload.sh --tag fix-space-shortcut Not-tested: Local XCTest run skipped per repo policy; regression coverage added for bare Space single-stroke and chord prefix dispatch.
The PR failed the workflow guard because the bare-Space shortcut fix grew files that are already tracked by the Swift file-length budget. Move the bare shortcut fast-path/cache helpers into a focused support file and split the new regression coverage into its own test file so the behavior stays covered without increasing existing file debt. Constraint: workflow-guard-tests enforces .github/swift-file-length-budget.tsv on large Swift files Rejected: Refresh the file-length budget | avoid accepting new file debt for a focused shortcut fix Confidence: high Scope-risk: narrow Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv Tested: ./scripts/reload.sh --tag fix-space-shortcut-ci
Greptile flagged that the bare-start shortcut cache observer used the posting thread for settings-change notifications. Match the existing AppDelegate observer pattern and invalidate the cache on the main queue so cache reads and writes stay on the same thread. Constraint: Keyboard shortcut settings notifications may be posted outside the main-thread event-routing path Rejected: Leave queue nil | callback delivery would depend on the posting thread Confidence: high Scope-risk: narrow Tested: git diff --check Tested: python3 scripts/swift_file_length_budget.py --budget .github/swift-file-length-budget.tsv Tested: ./scripts/reload.sh --tag fix-space-shortcut-review

Fixes #1711
Summary
spacewhile acceptingSpace,<space>,<Space>,spacebar, and literal-space bindings.Verification
git diff --checkweb/data/cmux-settings.schema.jsonandResources/Localizable.xcstringsNot run locally: XCTest/Bun test suites per repo policy.
Note
Medium Risk
Changes shortcut parsing and event-routing fast paths to allow bare Space and Space-prefixed chords, which could impact normal typing or shortcut dispatch behavior if edge cases are missed.
Overview
Adds first-class support for binding Space in custom shortcuts, canonicalizing config tokens to
space(acceptingSpace,<space>,spacebar, and literal whitespace) and wiring it through display strings, key-code resolution (kVK_Space), menu key equivalents, and schema validation.Updates shortcut routing to allow configured bare Space (including as a chord prefix) to be handled without breaking normal plain-key bypass logic by introducing
ShortcutBareStartRoutingwith cached configured bare-start keys and a newAppDelegate.shouldBypassPlainKeyShortcutRoutinggate; includes new regression tests covering parsing/round-tripping and bare-Space dispatch.Reviewed by Cursor Bugbot for commit 8d0c525. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Adds support for binding the Space key and updates event routing so configured bare Space shortcuts (including chord prefixes) are handled without impacting normal typing.
New Features
space; acceptsSpace,<space>,<Space>,spacebar, and literal space; resolves to kVK_Space (49); adds EN/JA display strings; updatesKeyEquivalentand menu equivalents.Refactors
shortcutFirstStroke,shortcutStroke, andunboundShortcutBinding; first/standalone stroke requires a modifier unless it’s Space; second stroke may be bare; accepts literal unshifted punctuation.""unbinds; whitespace-only tokens parse asspace. Focused tests cover parsing, kVK_Space resolution, settings round-trip, and routing for bare Space and Space chord prefixes.ShortcutBareStartRouting.swift, exposes minimal AppDelegate APIs for testability, and invalidates the bare-start cache on the main thread to match existing observer patterns.Written for commit 8d0c525. Summary will update on new commits.
Summary by CodeRabbit
New Features
Improvements
Tests