Skip to content

Commit 251b836

Browse files
author
aheizi
committed
feat: add shortcut to switch modes
1 parent e1836f8 commit 251b836

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

webview-ui/src/components/chat/ChatTextArea.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ interface ChatTextAreaProps {
3131
onHeightChange?: (height: number) => void
3232
mode: Mode
3333
setMode: (value: Mode) => void
34+
modeShortcutText: string
3435
}
3536

3637
const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
@@ -48,6 +49,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
4849
onHeightChange,
4950
mode,
5051
setMode,
52+
modeShortcutText,
5153
},
5254
ref,
5355
) => {
@@ -816,6 +818,11 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
816818
minWidth: "70px",
817819
flex: "0 0 auto",
818820
}}>
821+
<option
822+
disabled
823+
style={{ ...optionStyle, fontStyle: "italic", opacity: 0.6, padding: "2px 8px" }}>
824+
{modeShortcutText}
825+
</option>
819826
{getAllModes(customModes).map((mode) => (
820827
<option key={mode.slug} value={mode.slug} style={{ ...optionStyle }}>
821828
{mode.name}

webview-ui/src/components/chat/ChatView.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import TaskHeader from "./TaskHeader"
2828
import AutoApproveMenu from "./AutoApproveMenu"
2929
import { AudioType } from "../../../../src/shared/WebviewMessage"
3030
import { validateCommand } from "../../utils/command-validation"
31+
import { modes } from "../../../../src/shared/modes"
3132

3233
interface ChatViewProps {
3334
isHidden: boolean
@@ -38,6 +39,9 @@ interface ChatViewProps {
3839

3940
export const MAX_IMAGES_PER_MESSAGE = 20 // Anthropic limits to 20 images
4041

42+
const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0
43+
const modeShortcutText = `${isMac ? "⌘" : "Ctrl"} + . for next mode`
44+
4145
const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryView }: ChatViewProps) => {
4246
const {
4347
version,
@@ -963,6 +967,33 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
963967
isWriteToolAction,
964968
])
965969

970+
// Add this new function to handle mode switching
971+
const switchToNextMode = useCallback(() => {
972+
const currentModeIndex = modes.findIndex((m) => m.slug === mode)
973+
const nextModeIndex = (currentModeIndex + 1) % modes.length
974+
setMode(modes[nextModeIndex].slug)
975+
}, [mode, setMode])
976+
977+
// Add keyboard event handler
978+
const handleKeyDown = useCallback(
979+
(event: KeyboardEvent) => {
980+
// Check for Command + . (period)
981+
if ((event.metaKey || event.ctrlKey) && event.key === ".") {
982+
event.preventDefault() // Prevent default browser behavior
983+
switchToNextMode()
984+
}
985+
},
986+
[switchToNextMode],
987+
)
988+
989+
// Add event listener
990+
useEffect(() => {
991+
window.addEventListener("keydown", handleKeyDown)
992+
return () => {
993+
window.removeEventListener("keydown", handleKeyDown)
994+
}
995+
}, [handleKeyDown])
996+
966997
return (
967998
<div
968999
style={{
@@ -1171,6 +1202,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
11711202
}}
11721203
mode={mode}
11731204
setMode={setMode}
1205+
modeShortcutText={modeShortcutText}
11741206
/>
11751207

11761208
<div id="chat-view-portal" />

webview-ui/src/components/chat/__tests__/ChatTextArea.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ describe("ChatTextArea", () => {
4545
onHeightChange: jest.fn(),
4646
mode: defaultModeSlug,
4747
setMode: jest.fn(),
48+
modeShortcutText: "(⌘. for next mode)",
4849
}
4950

5051
beforeEach(() => {

0 commit comments

Comments
 (0)