fix(tui): keep tab behavior in shell mode
parent
a64f604d54
commit
c40b478756
|
|
@ -33,6 +33,7 @@ import { DialogAlert } from "../../ui/dialog-alert"
|
|||
import { useToast } from "../../ui/toast"
|
||||
import { useKV } from "../../context/kv"
|
||||
import { useTextareaKeybindings } from "../textarea-keybindings"
|
||||
import { shellPassthrough } from "./key"
|
||||
import { DialogSkill } from "../dialog-skill"
|
||||
|
||||
export type PromptProps = {
|
||||
|
|
@ -894,6 +895,10 @@ export function Prompt(props: PromptProps) {
|
|||
return
|
||||
}
|
||||
if (store.mode === "shell") {
|
||||
if (shellPassthrough(keybind, e, store.mode)) {
|
||||
e.stopPropagation()
|
||||
return
|
||||
}
|
||||
if ((e.name === "backspace" && input.visualCursor.offset === 0) || e.name === "escape") {
|
||||
setStore("mode", "normal")
|
||||
e.preventDefault()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import type { KeybindKey } from "@/cli/cmd/tui/context/keybind"
|
||||
|
||||
type Mode = "normal" | "shell"
|
||||
|
||||
type Key = {
|
||||
readonly name?: string
|
||||
readonly shift?: boolean
|
||||
}
|
||||
|
||||
export function shellPassthrough<E extends Key>(
|
||||
keybind: { readonly match: (key: KeybindKey, evt: E) => boolean | undefined },
|
||||
evt: E,
|
||||
mode: Mode,
|
||||
) {
|
||||
return mode === "shell" && (keybind.match("agent_cycle", evt) || keybind.match("agent_cycle_reverse", evt))
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { shellPassthrough } from "../../../src/cli/cmd/tui/component/prompt/key"
|
||||
|
||||
const key = (name: string, extra: { readonly shift?: boolean } = {}) => ({
|
||||
name,
|
||||
shift: false,
|
||||
...extra,
|
||||
})
|
||||
|
||||
describe("shellPassthrough", () => {
|
||||
test("allows tab agent-cycle bindings to pass through in shell mode", () => {
|
||||
const match = (target: string, evt: { readonly name?: string }) => target === "agent_cycle" && evt.name === "tab"
|
||||
expect(shellPassthrough({ match }, key("tab"), "shell")).toBe(true)
|
||||
})
|
||||
|
||||
test("allows reverse agent-cycle bindings to pass through in shell mode", () => {
|
||||
const match = (target: string, evt: { readonly name?: string; readonly shift?: boolean }) =>
|
||||
target === "agent_cycle_reverse" && evt.name === "tab" && evt.shift
|
||||
expect(shellPassthrough({ match }, key("tab", { shift: true }), "shell")).toBe(true)
|
||||
})
|
||||
|
||||
test("does not bypass agent-cycle outside shell mode", () => {
|
||||
const match = (target: string, evt: { readonly name?: string }) => target === "agent_cycle" && evt.name === "tab"
|
||||
expect(shellPassthrough({ match }, key("tab"), "normal")).toBe(false)
|
||||
})
|
||||
})
|
||||
Loading…
Reference in New Issue