Repository navigation
iOS: custom key combos / macros in the toolbar - #6108
austinywang wants to merge 21 commits into
Conversation
Lets users define custom key-combo and multi-step macro toolbar buttons in the mobile terminal shortcut bar — e.g. a single button that rotates an agent's permission mode (⇧ Tab), or a short sequence of keys and text. Model (CmuxMobileTerminalKit): - Add `ToolbarMacroStep` (.text / .keyCombo) with byte encoding. - Add `.macro([ToolbarMacroStep])` to `ToolbarActionPayload`; a tap sends the steps' bytes concatenated into one write (no inter-step delays). - `CustomToolbarAction.output` resolves every payload kind through `ToolbarMacroStep.output` so text/key-combo encoding lives in one place; `.text` / `.keyCombo` byte output is unchanged. - `TerminalSpecialKey: CaseIterable` for the editor's key picker. Editor (CmuxMobileShellUI): - `CustomToolbarActionEditorView` gains a Text vs Key Sequence type picker. Key Sequence is an ordered, reorderable list of steps: each a key combo (⇧⌃⌥ chips + special-key picker) or a text snippet. Unsupported combos are flagged and block Save so a saved macro never carries a dead step. - Pure `CustomToolbarActionDraft` (seed → build → validity) drives the view and is unit-tested without SwiftUI. - Settings row icon now distinguishes a text snippet from a key-combo/macro. The tap/send path is unchanged (it already sends `custom.output` as one blob), so macros need no wiring change. Tests: macro byte concatenation/codable + the ⇧Tab rotate-mode example (Kit suite), and draft seed/build/validity round-trips plus macro persistence through `TerminalAccessoryConfiguration` (cmuxFeatureTests, which runs in the iOS simulator test plan). All new user-facing strings localized (en + ja). Fixes #6087 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughAdds custom key-combo and macro support to the iOS toolbar. A new ChangesCustom Toolbar Key Combo / Macro Feature
Sequence DiagramsequenceDiagram
actor User
participant CustomToolbarActionEditorView
participant CustomToolbarActionDraft
participant ToolbarMacroStep
participant CustomToolbarAction
User->>CustomToolbarActionEditorView: Open editor (new or existing action)
CustomToolbarActionEditorView->>CustomToolbarActionDraft: init(action:) — seed from payload
User->>CustomToolbarActionEditorView: Switch mode to Key Sequence, add steps
CustomToolbarActionEditorView->>CustomToolbarActionDraft: Update mode/steps via `@State` bindings
User->>CustomToolbarActionEditorView: Tap Save (enabled when draft.isValid)
CustomToolbarActionEditorView->>CustomToolbarActionDraft: build(id:)
CustomToolbarActionDraft->>ToolbarMacroStep: Validate each step has output
CustomToolbarActionDraft-->>CustomToolbarActionEditorView: CustomToolbarAction (macro payload)
CustomToolbarActionEditorView->>CustomToolbarAction: onSave(action)
CustomToolbarAction->>ToolbarMacroStep: Reduce steps[].output into Data
ToolbarMacroStep-->>CustomToolbarAction: concatenated Data bytes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 1 warning)
✅ Passed checks (19 passed)
✨ 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 |
…-key-combos # Conflicts: # ios/cmux/Resources/Localizable.xcstrings
Greptile SummaryThis PR adds user-configurable key combos and multi-step macros to the iOS terminal toolbar. The model gains
Confidence Score: 5/5Safe to merge; the change is additive and the tap/send path is unchanged. The new model types are pure value types with exhaustive switches and correct nil-propagation. The editor refactor centralises save/build/validity in a testable pure struct, the two previously-flagged regressions are both fixed in this diff, the 50-step cap bounds all iteration, and all 25 new user-facing strings are translated in every supported locale. Tests cover byte concatenation, Codable round-trips, draft validity, and persistence. No files require special attention. Important Files Changed
Reviews (17): Last reviewed commit: "fix: restore debug settings localization..." | Re-trigger Greptile |
Address autoreview/Aziz file-organization findings by splitting the supporting types out of the editor files: - EditableMacroStep → EditableMacroStep.swift - ToolbarEditorModifierOption + the TerminalKeyModifier/TerminalSpecialKey editor presentation extensions → ToolbarEditorModifierOption.swift - the settings-row icon helper → a ToolbarActionPayload.settingsRowSystemImage extension (ToolbarActionPayload+SettingsIcon.swift) instead of a private static func on the view (a file-scope free func would trip the iOS package-conventions lint, so an extension property is the compliant home) No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- P1: the step-list reorder control was shown only when steps.count > 1, so deleting from 2 steps to 1 hid it while edit mode stayed active, trapping the user. Own the EditMode state, show the control whenever the list is non-empty, and force edit mode inactive when the list empties or the editor leaves key-sequence mode. - P2: an empty text step silently disabled Save with no cue. Add a symmetric inline caption (mirroring the unsupported-key-combo warning) so the greyed Save button is explained. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-key-combos Resolve swift-file-length-budget.tsv conflict by regenerating the budget from the merged working tree (python3 scripts/swift_file_length_budget.py --write-budget). Both sides edited ContentView.swift, TerminalController.swift, WorkspaceUnitTests.swift, and WorkspaceRemoteConnectionTests.swift, so neither side's recorded line count matched the merged result; the regenerated counts match the actual merged files and the budget check passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fixes #6087
What & why
Users asked to bind their own key combos / macros to iOS terminal-toolbar buttons — e.g. a single button that rotates an agent's permission mode (⇧ Tab) or runs a short key/text sequence.
The model already had
CustomToolbarActionwith.textand.keyCombopayloads, but the editor only ever produced.text(key combos weren't user-creatable) and there was no macro (multi-step) support. This PR closes that gap.Changes
Model —
CmuxMobileTerminalKitToolbarMacroStep(.text/.keyCombo) with byte encoding..macro([ToolbarMacroStep])case onToolbarActionPayload. A tap sends the steps' bytes concatenated into one write — no inter-step delays (no sleeps).CustomToolbarAction.outputnow resolves every payload kind throughToolbarMacroStep.output, so text/key-combo encoding lives in one place..text/.keyCombobyte output is unchanged.TerminalSpecialKey: CaseIterablefor the editor's key picker.Editor —
CmuxMobileShellUICustomToolbarActionEditorViewgains a Text vs Key Sequence type picker. Key Sequence is an ordered, reorderable list of steps; each step is either a key combo (⇧ ⌃ ⌥ chips + special-key picker) or a text snippet. Unsupported combos are flagged inline and block Save, so a saved macro never carries a dead step.CustomToolbarActionDraft(seed → build → validity) drives the view and is unit-tested without SwiftUI.The tap/send path is unchanged — it already sends
custom.outputas a single blob and clears armed modifiers first — so macros required no wiring change.How to verify (iOS Simulator)
cmux-iosapp, open a terminal, tap the customize control on the keyboard toolbar → Terminal Shortcuts → Add Custom Action.ESC [ Z(Shift+Tab) — e.g. rotates Claude's permission mode in a running agent.Tests
CmuxMobileTerminalKitTests): macro byte concatenation, skipping unresolvable steps, all-empty → nil, Codable round-trip, and the ⇧ Tab rotate-mode example. Run locally viaswift test --package-path Packages/CmuxMobileTerminalKit(✅ 85 passing).cmuxFeatureTests(runs in the iOS simulator test plan):CustomToolbarActionDraftseed/build/validity round-trips, the rotate-permission-mode scenario built end-to-end, and macro persistence throughTerminalAccessoryConfiguration.Localization
All new user-facing strings added to
ios/cmux/Resources/Localizable.xcstringswith en + ja (25 keys; additive diff, no existing entries changed). Audit: no bare user-facing English in the changed Swift files (only SF Symbol names, key glyphs ⇧⌃⌥, and accessibility identifiers remain).Scope note
Part of the iOS toolbar-customization cluster (#6086–#6091) being worked in parallel. Kept tightly scoped to #6087; expect to rebase against main / siblings on landing. Control-letter combos (Ctrl+R, etc.) are a deliberate follow-up — the built-in ^C/^D/^Z/^L buttons and text steps already cover the common cases.
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Adds custom key combos and multi-step macros to iOS terminal toolbar buttons so one tap can send ⇧Tab or run a short sequence. Fixes #6087. Steps send as one write with no delays; invalid steps are blocked in the editor.
New Features
CmuxMobileTerminalKit:ToolbarMacroStep(.text/.keyCombo) with encoding;ToolbarActionPayload.macro([ToolbarMacroStep]); unified bytes viaToolbarMacroStep.output;TerminalSpecialKey: CaseIterable.CmuxMobileShellUI: Editor adds Text vs Key Sequence; reorderable steps with ⇧⌃⌥ chips and a special‑key picker; legacy.keyComboopens as a one‑step sequence; settings list icon reflects payload viaToolbarActionPayload.settingsRowSystemImage. PureCustomToolbarActionDraft(seed → build → validity) with a 50‑step cap.TerminalAccessoryConfiguration; new strings (en, ja).Bug Fixes
EditModeto avoid getting stuck; reset when steps empty or leaving Key Sequence; show reorder control whenever steps exist.Written for commit d390db1. Summary will update on new commits.
Summary by CodeRabbit