diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index fce9917c2e7..c45a4630c92 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -64,6 +64,11 @@ export function Prompt(props: PromptProps) { const renderer = useRenderer() const { theme, syntax } = useTheme() + const cursorStyle = createMemo(() => ({ + style: "block" as const, + blinking: sync.data.config.tui?.cursor_blinking ?? true, + })) + function promptModelWarning() { toast.show({ variant: "warning", @@ -271,6 +276,7 @@ export function Prompt(props: PromptProps) { createEffect(() => { if (props.disabled) input.cursorColor = theme.backgroundElement if (!props.disabled) input.cursorColor = theme.text + input.cursorStyle = cursorStyle() }) const [store, setStore] = createStore<{ @@ -794,11 +800,13 @@ export function Prompt(props: PromptProps) { input = r setTimeout(() => { input.cursorColor = theme.text + input.cursorStyle = cursorStyle() }, 0) }} onMouseDown={(r: MouseEvent) => r.target?.focus()} focusedBackgroundColor={theme.backgroundElement} cursorColor={theme.text} + cursorStyle={cursorStyle()} syntaxStyle={syntax()} /> diff --git a/packages/opencode/src/cli/cmd/tui/ui/dialog-prompt.tsx b/packages/opencode/src/cli/cmd/tui/ui/dialog-prompt.tsx index 4b4c635a529..cd7098700e0 100644 --- a/packages/opencode/src/cli/cmd/tui/ui/dialog-prompt.tsx +++ b/packages/opencode/src/cli/cmd/tui/ui/dialog-prompt.tsx @@ -1,7 +1,8 @@ import { TextareaRenderable, TextAttributes } from "@opentui/core" import { useTheme } from "../context/theme" import { useDialog, type DialogContext } from "./dialog" -import { onMount, type JSX } from "solid-js" +import { useSync } from "../context/sync" +import { createMemo, onMount, type JSX } from "solid-js" import { useKeyboard } from "@opentui/solid" export type DialogPromptProps = { @@ -16,8 +17,14 @@ export type DialogPromptProps = { export function DialogPrompt(props: DialogPromptProps) { const dialog = useDialog() const { theme } = useTheme() + const sync = useSync() let textarea: TextareaRenderable + const cursorStyle = createMemo(() => ({ + style: "block" as const, + blinking: sync.data.config.tui?.cursor_blinking ?? true, + })) + useKeyboard((evt) => { if (evt.name === "return") { props.onConfirm?.(textarea.plainText) @@ -52,6 +59,7 @@ export function DialogPrompt(props: DialogPromptProps) { textColor={theme.text} focusedTextColor={theme.text} cursorColor={theme.text} + cursorStyle={cursorStyle()} /> diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 34e3eea7923..4275a784542 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -490,6 +490,7 @@ export namespace Config { .enum(["auto", "stacked"]) .optional() .describe("Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column"), + cursor_blinking: z.boolean().optional().describe("Enable or disable cursor blinking in the prompt input box"), }) export const Layout = z.enum(["auto", "stretch"]).meta({ diff --git a/packages/opencode/test/config/config.test.ts b/packages/opencode/test/config/config.test.ts index 2ff8c01cdb0..624464d44d9 100644 --- a/packages/opencode/test/config/config.test.ts +++ b/packages/opencode/test/config/config.test.ts @@ -501,3 +501,26 @@ test("deduplicates duplicate plugins from global and local configs", async () => }, }) }) + +test("handles TUI cursor blinking configuration", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.json"), + JSON.stringify({ + $schema: "https://opencode.ai/config.json", + tui: { + cursor_blinking: false, + }, + }), + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await Config.get() + expect(config.tui?.cursor_blinking).toBe(false) + }, + }) +}) diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index dade066c070..0fd5017f3f7 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -1214,6 +1214,10 @@ export type Config = { * Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column */ diff_style?: "auto" | "stacked" + /** + * Enable or disable cursor blinking in the prompt input box + */ + cursor_blinking?: boolean } /** * Command configuration, see https://opencode.ai/docs/commands