-
Couldn't load subscription status.
- Fork 10
🤖 Add customizable F-key macros #305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add F1-F10 keybind bar above workspace title - Click F-key buttons to edit macro messages - Press F-keys to send messages (supports slash commands) - Configuration stored in ~/.cmux/keybinds.jsonc - Full IPC plumbing with type-safe backend service - 8 unit tests for keybind service (all passing) Backend: - KeybindService for loading/saving keybinds.jsonc - IPC handlers for get/set operations - Type definitions for keybind actions Frontend: - FKeyBar component showing F1-F10 buttons - EditKeybindModal for configuring macros - useFKeyBinds hook for global keyboard handling - Extended ChatInputAPI with sendMessage() method Generated with `cmux`
- Reduced vertical spacing (3px padding instead of 4px) - Added gradient background for depth - Added subtle shadow and bottom border for 3D effect - Buttons raise on hover, depress on click - Smaller font size (10px) for compact look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
src/components/ChatInput.tsx
Outdated
| // Programmatically send a message (for F-key macros, etc.) | ||
| const sendMessageProgrammatically = useCallback( | ||
| (message: string) => { | ||
| if (!message.trim() || disabled || isSending || isCompacting) { | ||
| return; | ||
| } | ||
|
|
||
| // Set the input value and let the regular send flow handle it | ||
| setInput(message); | ||
| // Focus the input to show what's being sent | ||
| if (inputRef.current) { | ||
| inputRef.current.focus(); | ||
| } | ||
| // Trigger send after a brief delay to ensure state updates | ||
| setTimeout(() => { | ||
| void handleSend(); | ||
| }, 10); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Programmatic send uses stale input state
The new sendMessage helper inserts the macro text and then triggers handleSend via a delayed callback, but handleSend captures the input value from the previous render. When the timeout fires, the closure still sees the old (often empty) input and returns immediately, leaving the macro message sitting in the input field instead of being sent. This means F‑key macros don’t actually transmit anything unless the user manually hits Enter afterward. The helper needs to send the message without relying on the stale closure—e.g. by passing the text directly into the send routine or by using a ref to a stable sender.
Useful? React with 👍 / 👎.
- Rename ModalContent to KeybindModalContent to avoid conflict with Modal's built-in ModalContent - Remove min-width: 500px (Modal already handles responsive width) - Fixes textarea overflow issue
- If chat input has text: append macro message with space separator - If chat input is empty: set message and auto-send immediately - Move cursor to end after appending for easy editing
- Directly invoke send logic instead of relying on setState + handleSend - Duplicate minimal send logic to avoid state timing issues - Handles all command types (/clear, /truncate, /compact, etc.) - Auto-send now works reliably when input is empty
- Refactored handleSend to accept optional messageOverride parameter - Added clearInputIfNeeded helper to avoid clearing on programmatic sends - Simplified sendMessageProgrammatically from 150+ lines to ~25 lines - Eliminated complete duplication of command parsing and send logic - Single source of truth for all message sending This fixes the messiness from having duplicate send logic in two places.
- Positioned FKeyBar directly above ChatInput textarea - Makes more sense since F-keys interact with chat input - Adjusted styling: removed bottom border, adjusted padding - Background matches chat input section for seamless integration
- Changed background from #252526 to #1e1e1e - Now blends seamlessly with chat output area
- Added onFocusChange prop to ChatInput component - Track focus state in AIView with chatInputFocused - Conditionally render FKeyBar only when input is focused - Added smooth slide-down animation (0.2s ease-out) - Cleaner UI: F-keys only visible when relevant
Overview
Adds support for customizable F1-F10 macro keys with visual editing UI.
Features
/edit,/compact, etc.~/.cmux/keybinds.jsoncUI Components
FKeyBar: Displays F1-F10 buttons with message previewsEditKeybindModal: Modal dialog for editing macrosBackend
KeybindService: Handles loading/saving keybinds.jsonckeybinds:getandkeybinds:setchannelsTesting
Example Usage
continueor/edit Add testsFile Structure
Configuration stored in
~/.cmux/keybinds.jsonc:Architecture
Implementation Details
Files Created:
src/types/keybinds.tssrc/services/keybindService.ts+ testssrc/components/FKeyBar.tsxsrc/components/EditKeybindModal.tsxsrc/hooks/useFKeyBinds.tsFiles Modified:
src/components/AIView.tsx- Integrated FKeyBar and modalsrc/components/ChatInput.tsx- Extended API with sendMessage()src/services/ipcMain.ts- Added keybind handlerssrc/constants/ipc-constants.ts- Added channelssrc/preload.ts- Exposed keybinds APIsrc/types/ipc.ts- Added to IPCApi interfaceGenerated with
cmux