Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 26 additions & 26 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/tui/src/component/prompt/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ export function Prompt(props: PromptProps) {
const content = await openEditor({
renderer,
value,
config: tuiConfig.editor,
cwd:
(project.instance.path().worktree === "/" ? undefined : project.instance.path().worktree) ||
project.instance.directory() ||
Expand Down
10 changes: 10 additions & 0 deletions packages/tui/src/config/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ export const Prompt = Schema.Struct({
}),
}).annotate({ description: "Prompt size settings" })

export const EditorConfig = Schema.Struct({
editor_path: Schema.optional(Schema.String).annotate({
description: "Editor command (overrides VISUAL/EDITOR environment variables)",
}),
editor_temp_dir: Schema.optional(Schema.String).annotate({
description: "Temporary directory for editor temp files (default: OS tmp dir)",
}),
}).annotate({ description: "Editor settings" })

export const Info = Schema.Struct({
$schema: Schema.optional(Schema.String),
theme: Schema.optional(Schema.String),
Expand All @@ -58,6 +67,7 @@ export const Info = Schema.Struct({
plugin_enabled: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)),
leader_timeout: Schema.optional(LeaderTimeout),
attention: Schema.optional(Attention),
editor: Schema.optional(EditorConfig),
prompt: Schema.optional(Prompt),
scroll_speed: Schema.optional(ScrollSpeed).annotate({ description: "TUI scroll speed" }),
scroll_acceleration: Schema.optional(ScrollAcceleration),
Expand Down
17 changes: 14 additions & 3 deletions packages/tui/src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,21 @@ export function normalizePromptContent(content: string) {
return content
}

export async function openEditor(input: { value: string; renderer: CliRenderer; cwd?: string; stdin?: EditorStdio }) {
const editor = process.env.VISUAL || process.env.EDITOR
export type EditorConfig = {
editor_path?: string
editor_temp_dir?: string
}

export async function openEditor(input: {
value: string
renderer: CliRenderer
cwd?: string
stdin?: EditorStdio
config?: EditorConfig
}) {
const editor = input.config?.editor_path || process.env.VISUAL || process.env.EDITOR
if (!editor) return
const file = path.join(os.tmpdir(), `${Date.now()}.md`)
const file = path.join(input.config?.editor_temp_dir ?? os.tmpdir(), `${Date.now()}.md`)
await writeFile(file, input.value)
input.renderer.suspend()
input.renderer.currentRenderBuffer.clear()
Expand Down
9 changes: 8 additions & 1 deletion packages/tui/src/routes/session/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -978,10 +978,11 @@ export function Session() {
)

if (options.openWithoutSaving) {
// Just open in editor without saving
// Just open in editor without saving — use os.tmpdir() not user-configured temp dir
await openEditor({
renderer,
value: transcript,
config: { ...tuiConfig.editor, editor_temp_dir: undefined },
cwd:
(project.instance.path().worktree === "/" ? undefined : project.instance.path().worktree) ||
project.instance.directory() ||
Expand All @@ -998,11 +999,17 @@ export function Session() {
const result = await openEditor({
renderer,
value: transcript,
config: tuiConfig.editor,
cwd:
(project.instance.path().worktree === "/" ? undefined : project.instance.path().worktree) ||
project.instance.directory() ||
paths.cwd,
}).catch((e) => {
// File was already saved above. Opening the editor afterward is
// best-effort — swallow errors so they don't reach the outer
// catch block, which would incorrectly show "Failed to export".
})

if (result !== undefined) {
await writeExport(filepath, result)
}
Expand Down
Loading