Skip to content

fix bonesplit to show custom modifier keys#32

Open
gmmeyer wants to merge 1 commit intomanaflow-ai:mainfrom
gmmeyer:main
Open

fix bonesplit to show custom modifier keys#32
gmmeyer wants to merge 1 commit intomanaflow-ai:mainfrom
gmmeyer:main

Conversation

@gmmeyer
Copy link

@gmmeyer gmmeyer commented Mar 19, 2026

i wanted to allow custom modifier keys to work on cmux, I'll edit the cmux PR with this PR number and do the reverse here. I tested this on cmux and it works.

manaflow-ai/cmux#1819


Summary by cubic

Show pane/tab shortcut hints using the user’s configured modifier keys and display the correct symbols. Hints now trigger on both surface and workspace modifiers, matching cmux settings.

  • Bug Fixes
    • Respect custom digit shortcut modifiers via UserDefaults keys digitShortcutSurfaceModifierFlags and digitShortcutWorkspaceModifierFlags (defaults: .control and .command).
    • Render the correct modifier symbol on hint pills based on combined flags (⌃⌥⇧⌘).
    • Trigger hint overlay when either the surface or workspace modifier is held.

Written for commit b5a0c93. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes & Improvements
    • Enhanced tab shortcut modifier handling to better reflect user preferences and system state.
    • Improved keyboard shortcut hint display to dynamically reflect configured modifier keys.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link

coderabbitai bot commented Mar 19, 2026

📝 Walkthrough

Walkthrough

The TabControlShortcutModifier enum was refactored to replace two fixed cases (.control, .command) with a flexible .flags(NSEvent.ModifierFlags) case. TabControlShortcutHintPolicy now reads configurable modifier flags from UserDefaults, applies defaults, and returns the corresponding flags value when held modifiers match.

Changes

Cohort / File(s) Summary
Tab Shortcut Modifier Refactoring
Sources/Bonsplit/Internal/Views/TabBarView.swift
Replaced hardcoded modifier cases with flexible .flags(NSEvent.ModifierFlags) representation. Extended TabControlShortcutHintPolicy to read "surface" and "workspace" modifier flags from UserDefaults with defaults. Added symbolString(for:) and surfaceModifierSymbol(defaults:) helpers. Updated TabControlShortcutKeyMonitor initialization and guard logic to work with the new flags-based approach.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Flags now dance where cases stood,
UserDefaults bring configurability good,
No more hardcoded control or command,
Shortcuts bloom at the keyboard's hand! ⌨️✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix bonesplit to show custom modifier keys' is directly related to the main change in the pull request, which updates the tab shortcut modifier representation to support configurable custom modifier keys from UserDefaults instead of fixed control/command cases.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can generate a title for your PR based on the changes with custom instructions.

Set the reviews.auto_title_instructions setting to generate a title for your PR based on the changes in the PR with custom instructions.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Sources/Bonsplit/Internal/Views/TabBarView.swift">

<violation number="1" location="Sources/Bonsplit/Internal/Views/TabBarView.swift:735">
P2: Resolved modifier flags are not validated after masking; invalid nonzero stored values can become empty flags and incorrectly trigger hint mode with no modifier pressed.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

private static func resolvedSurfaceFlags(defaults: UserDefaults) -> NSEvent.ModifierFlags {
let raw = defaults.integer(forKey: surfaceModifierKey)
guard raw != 0 else { return defaultSurfaceFlags }
return NSEvent.ModifierFlags(rawValue: UInt(raw)).intersection(.deviceIndependentFlagsMask)
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 19, 2026

Choose a reason for hiding this comment

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

P2: Resolved modifier flags are not validated after masking; invalid nonzero stored values can become empty flags and incorrectly trigger hint mode with no modifier pressed.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Sources/Bonsplit/Internal/Views/TabBarView.swift, line 735:

<comment>Resolved modifier flags are not validated after masking; invalid nonzero stored values can become empty flags and incorrectly trigger hint mode with no modifier pressed.</comment>

<file context>
@@ -702,6 +712,34 @@ enum TabControlShortcutHintPolicy {
+    private static func resolvedSurfaceFlags(defaults: UserDefaults) -> NSEvent.ModifierFlags {
+        let raw = defaults.integer(forKey: surfaceModifierKey)
+        guard raw != 0 else { return defaultSurfaceFlags }
+        return NSEvent.ModifierFlags(rawValue: UInt(raw)).intersection(.deviceIndependentFlagsMask)
+    }
+
</file context>
Fix with Cubic

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/Bonsplit/Internal/Views/TabBarView.swift (1)

671-682: ⚠️ Potential issue | 🟠 Major

Refresh the hint-policy tests for the new flags-based return value.

Line 681 and Line 682 now return .flags(...), but Tests/BonsplitTests/BonsplitTests.swift:623-624 still expect .command and .control. That leaves the test target broken until those assertions are updated to the new enum shape.

Suggested follow-up in Tests/BonsplitTests/BonsplitTests.swift
-XCTAssertEqual(TabControlShortcutHintPolicy.hintModifier(for: [.command], defaults: defaults), .command)
-XCTAssertEqual(TabControlShortcutHintPolicy.hintModifier(for: [.control], defaults: defaults), .control)
+XCTAssertEqual(
+    TabControlShortcutHintPolicy.hintModifier(for: [.command], defaults: defaults),
+    .flags([.command])
+)
+XCTAssertEqual(
+    TabControlShortcutHintPolicy.hintModifier(for: [.control], defaults: defaults),
+    .flags([.control])
+)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/Bonsplit/Internal/Views/TabBarView.swift` around lines 671 - 682, The
tests still assert the old enum cases (.command and .control) but the function
TabBarView.hintModifier(for:defaults:) now returns
TabControlShortcutModifier.flags(...) with surface/workspace masks; update the
test assertions in the BonsplitTests to expect .flags(...) instead of
.command/.control and construct the expected value by calling
resolvedSurfaceFlags(defaults:) and resolvedWorkspaceFlags(defaults:) (or by
using the same flag masks used in production) so the assertions compare
TabControlShortcutModifier.flags(resolvedSurfaceFlags(...)) and
TabControlShortcutModifier.flags(resolvedWorkspaceFlags(...)).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@Sources/Bonsplit/Internal/Views/TabBarView.swift`:
- Around line 671-682: The tests still assert the old enum cases (.command and
.control) but the function TabBarView.hintModifier(for:defaults:) now returns
TabControlShortcutModifier.flags(...) with surface/workspace masks; update the
test assertions in the BonsplitTests to expect .flags(...) instead of
.command/.control and construct the expected value by calling
resolvedSurfaceFlags(defaults:) and resolvedWorkspaceFlags(defaults:) (or by
using the same flag masks used in production) so the assertions compare
TabControlShortcutModifier.flags(resolvedSurfaceFlags(...)) and
TabControlShortcutModifier.flags(resolvedWorkspaceFlags(...)).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 52396ded-4d5d-4333-979d-c89f3c6914ea

📥 Commits

Reviewing files that changed from the base of the PR and between efa23f4 and b5a0c93.

📒 Files selected for processing (1)
  • Sources/Bonsplit/Internal/Views/TabBarView.swift

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.

1 participant