diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index c98d4e2633..833c8dc8c3 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -727,6 +727,15 @@ function App(props: { onSnapshot?: () => Promise }) { dialog.clear() }, }, + { + title: kv.get("file_context_enabled", true) ? "Disable file context" : "Enable file context", + value: "app.toggle.file_context", + category: "System", + onSelect: (dialog) => { + kv.set("file_context_enabled", !kv.get("file_context_enabled", true)) + dialog.clear() + }, + }, { title: kv.get("diff_wrap_mode", "word") === "word" ? "Disable diff wrapping" : "Enable diff wrapping", value: "app.toggle.diffwrap", 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 05afd33699..7fead6fdbc 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -112,9 +112,10 @@ export function Prompt(props: PromptProps) { const animationsEnabled = createMemo(() => kv.get("animations_enabled", true)) const list = createMemo(() => props.placeholders?.normal ?? []) const shell = createMemo(() => props.placeholders?.shell ?? []) - const editorPath = createMemo(() => editor.selection()?.filePath) + const fileContextEnabled = createMemo(() => kv.get("file_context_enabled", true)) + const editorPath = createMemo(() => (fileContextEnabled() ? editor.selection()?.filePath : undefined)) const editorSelectionLabel = createMemo(() => { - const selection = editor.selection()?.selection + const selection = fileContextEnabled() ? editor.selection()?.selection : undefined if (!selection) return if (selection.start.line === selection.end.line && selection.start.character === selection.end.character) return if (selection.start.line === selection.end.line) return `#${selection.start.line}` @@ -746,7 +747,7 @@ export function Prompt(props: PromptProps) { // Capture mode before it gets reset const currentMode = store.mode const variant = local.model.variant.current() - const editorSelection = editor.selection() + const editorSelection = fileContextEnabled() ? editor.selection() : undefined const editorParts = editorSelection ? [ { @@ -755,13 +756,17 @@ export function Prompt(props: PromptProps) { text: (() => { const start = editorSelection.selection.start const end = editorSelection.selection.end + + let text = "" if (start.line === end.line && start.character === end.character) { - return `Note: The user opened the file "${editorSelection.filePath}".` + text = `Note: The user opened the file "${editorSelection.filePath}".` + } else if (start.line === end.line) { + text = `Note: The user selected line ${start.line + 1} from "${editorSelection.filePath}". \`\`\`${editorSelection.text}\`\`\`\n\n` + } else { + text = `Note: The user selected lines ${start.line + 1} to ${end.line + 1} from "${editorSelection.filePath}". \`\`\`${editorSelection.text}\`\`\`\n\n` } - if (start.line === end.line) { - return `Note: The user selected line ${start.line} from "${editorSelection.filePath}": ${editorSelection.text}` - } - return `Note: The user selected lines ${start.line} to ${end.line} from "${editorSelection.filePath}": ${editorSelection.text}` + + return `${text} This may or may not be relevant to the current task.\n` })(), synthetic: true, metadata: { @@ -835,6 +840,7 @@ export function Prompt(props: PromptProps) { ], }) .catch(() => {}) + editor.clearSelection() } history.append({ ...store.prompt, diff --git a/packages/opencode/src/cli/cmd/tui/context/editor.ts b/packages/opencode/src/cli/cmd/tui/context/editor.ts index 7f2c46d086..aff5f4a6ba 100644 --- a/packages/opencode/src/cli/cmd/tui/context/editor.ts +++ b/packages/opencode/src/cli/cmd/tui/context/editor.ts @@ -108,9 +108,11 @@ export const { use: useEditorContext, provider: EditorContextProvider } = create send({ id: requestID, method, params }) } - const scheduleReconnect = (delay: number) => { + const scheduleReconnect = () => { if (closed) return if (reconnect) clearTimeout(reconnect) + attempt += 1 + const delay = Math.min(1000 * 2 ** (attempt - 1), 10_000) reconnect = setTimeout(connect, delay) } @@ -122,7 +124,7 @@ export const { use: useEditorContext, provider: EditorContextProvider } = create const dbPath = resolveZedDbPath() if (!dbPath) { setStore("status", "disabled") - scheduleReconnect(1000) + scheduleReconnect() return } zedSelection ??= resolveZedSelection(dbPath) @@ -143,7 +145,7 @@ export const { use: useEditorContext, provider: EditorContextProvider } = create .finally(() => { zedSelection = undefined }) - scheduleReconnect(1000) + scheduleReconnect() return } @@ -207,13 +209,11 @@ export const { use: useEditorContext, provider: EditorContextProvider } = create if (closed) return setStore("status", "connecting") - attempt += 1 - const delay = Math.min(1000 * 2 ** (attempt - 1), 30000) - scheduleReconnect(delay) + scheduleReconnect() }) } - scheduleReconnect(0) + connect() onCleanup(() => { closed = true @@ -232,6 +232,9 @@ export const { use: useEditorContext, provider: EditorContextProvider } = create selection() { return store.selection }, + clearSelection() { + setStore("selection", undefined) + }, onMention(listener: (mention: EditorMention) => void) { mentionListeners.add(listener) return () => mentionListeners.delete(listener)