11import { useFilteredList } from "@opencode-ai/ui/hooks"
2- import { createEffect , on , Component , Show , For , onCleanup , Switch , Match , createMemo , createSignal } from "solid-js"
2+ import { createEffect , on , Component , Show , onCleanup , Switch , Match , createMemo , createSignal } from "solid-js"
33import { createStore } from "solid-js/store"
44import { createFocusSignal } from "@solid-primitives/active-element"
55import { useLocal } from "@/context/local"
@@ -26,6 +26,7 @@ import type { IconName } from "@opencode-ai/ui/icons/provider"
2626import { Tooltip , TooltipKeybind } from "@opencode-ai/ui/tooltip"
2727import { IconButton } from "@opencode-ai/ui/icon-button"
2828import { Select } from "@opencode-ai/ui/select"
29+ import { RadioGroup } from "@opencode-ai/ui/radio-group"
2930import { useDialog } from "@opencode-ai/ui/context/dialog"
3031import { ModelSelectorPopover } from "@/components/dialog-select-model"
3132import { DialogSelectModelUnpaid } from "@/components/dialog-select-model-unpaid"
@@ -249,7 +250,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
249250 return messages . some ( ( m ) => m . role === "user" )
250251 } )
251252
252- const MAX_HISTORY = 100
253253 const [ history , setHistory ] = persisted (
254254 Persist . global ( "prompt-history" , [ "prompt-history.v1" ] ) ,
255255 createStore < {
@@ -319,6 +319,9 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
319319 requestAnimationFrame ( ( ) => editorRef ?. focus ( ) )
320320 }
321321
322+ const shellModeKey = "mod+shift+x"
323+ const normalModeKey = "mod+shift+e"
324+
322325 command . register ( "prompt-input" , ( ) => [
323326 {
324327 id : "file.attach" ,
@@ -328,6 +331,22 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
328331 disabled : store . mode !== "normal" ,
329332 onSelect : pick ,
330333 } ,
334+ {
335+ id : "prompt.mode.shell" ,
336+ title : language . t ( "command.prompt.mode.shell" ) ,
337+ category : language . t ( "command.category.session" ) ,
338+ keybind : shellModeKey ,
339+ disabled : store . mode === "shell" ,
340+ onSelect : ( ) => setMode ( "shell" ) ,
341+ } ,
342+ {
343+ id : "prompt.mode.normal" ,
344+ title : language . t ( "command.prompt.mode.normal" ) ,
345+ category : language . t ( "command.category.session" ) ,
346+ keybind : normalModeKey ,
347+ disabled : store . mode === "normal" ,
348+ onSelect : ( ) => setMode ( "normal" ) ,
349+ } ,
331350 ] )
332351
333352 const closePopover = ( ) => setStore ( "popover" , null )
@@ -1339,45 +1358,35 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
13391358 </ TooltipKeybind >
13401359 </ Show >
13411360 </ div >
1342-
1343- < div class = "shrink-0" >
1344- < div
1345- data-component = "prompt-mode-toggle"
1346- class = "relative h-7 w-[68px] rounded-[4px] bg-surface-inset-base border border-[0.5px] border-border-weak-base p-0 flex items-center gap-1 overflow-visible"
1347- >
1348- < div
1349- class = "absolute inset-y-0 left-0 w-[calc((100%-4px)/2)] rounded-[4px] bg-surface-raised-stronger-non-alpha shadow-[var(--shadow-xs-border)] transition-transform duration-200 ease-out will-change-transform"
1350- style = { {
1351- transform : store . mode === "shell" ? "translateX(0px)" : "translateX(calc(100% + 4px))" ,
1352- } }
1353- />
1354- < button
1355- type = "button"
1356- class = "relative z-10 flex-1 h-full p-0.5 flex items-center justify-center"
1357- aria-pressed = { store . mode === "shell" }
1358- onClick = { ( ) => setMode ( "shell" ) }
1359- >
1360- < div
1361- class = "w-full h-full flex items-center justify-center rounded-[2px] transition-colors hover:bg-surface-inset-base"
1362- classList = { { "hover:bg-transparent" : store . mode === "shell" } }
1363- >
1364- < Icon name = "console" class = "size-[18px]" />
1365- </ div >
1366- </ button >
1367- < button
1368- type = "button"
1369- class = "relative z-10 flex-1 h-full p-0.5 flex items-center justify-center"
1370- aria-pressed = { store . mode === "normal" }
1371- onClick = { ( ) => setMode ( "normal" ) }
1372- >
1373- < div
1374- class = "w-full h-full flex items-center justify-center rounded-[2px] transition-colors hover:bg-surface-inset-base"
1375- classList = { { "hover:bg-transparent" : store . mode === "normal" } }
1361+ < div class = "shrink-0" data-component = "prompt-mode-toggle" >
1362+ < RadioGroup
1363+ options = { [ "shell" , "normal" ] as const }
1364+ current = { store . mode }
1365+ value = { ( mode ) => mode }
1366+ label = { ( mode ) => (
1367+ < TooltipKeybind
1368+ placement = "top"
1369+ gutter = { 4 }
1370+ title = { language . t ( mode === "shell" ? "command.prompt.mode.shell" : "command.prompt.mode.normal" ) }
1371+ keybind = { command . keybind ( mode === "shell" ? "prompt.mode.shell" : "prompt.mode.normal" ) }
1372+ class = "size-full flex items-center justify-center"
13761373 >
1377- < Icon name = "prompt" class = "size-[18px]" />
1378- </ div >
1379- </ button >
1380- </ div >
1374+ < Icon
1375+ name = { mode === "shell" ? "console" : "prompt" }
1376+ class = "size-[18px]"
1377+ classList = { {
1378+ "text-icon-strong-base" : mode === "shell" && store . mode === "shell" ,
1379+ "text-icon-interactive-base" : mode === "normal" && store . mode === "normal" ,
1380+ "text-icon-weak" : store . mode !== mode ,
1381+ } }
1382+ />
1383+ </ TooltipKeybind >
1384+ ) }
1385+ onSelect = { ( mode ) => mode && setMode ( mode ) }
1386+ fill
1387+ pad = "none"
1388+ class = "w-[68px]"
1389+ />
13811390 </ div >
13821391 </ div >
13831392 </ div >
0 commit comments