Created
December 24, 2025 09:13
-
-
Save colelawrence/125a32cdc15e004f6729360fe3bec1eb to your computer and use it in GitHub Desktop.
Edit text in system editor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| type PathString = string & { __brand: "path" } | |
| function call<R>(fn: () => R) { return fn(); } | |
| /** TODO: Return null if the user cancels/doesn't save the file (like in git) */ | |
| export async function editTextInSystemEditor(originalText: string): Promise<string | null> { | |
| // Create a unique temp directory using Bun's file APIs | |
| const tmpDir = `/tmp/context-edit-${Date.now()}-${Math.random().toString(36).slice(2)}`; | |
| await Bun.$`mkdir -p ${tmpDir}`; | |
| const tmpFile = `${tmpDir}/prompt-edit.txt` as PathString; | |
| try { | |
| await Bun.write(tmpFile, originalText); | |
| const args = | |
| (await guessEditorDarwin(tmpFile)) || | |
| call(() => { | |
| const editor = process.env.EDITOR || "code"; | |
| const vsCodeBased = /^(code|cursor|windsurf|codeium)$|^code\-|/.test(editor); | |
| return vsCodeBased ? [editor, "--wait", tmpFile] : [editor, tmpFile]; | |
| }); | |
| const child = Bun.spawn(args, { | |
| stdio: ["inherit", "inherit", "inherit"], | |
| }); | |
| await child.exited; | |
| let editedText = originalText; | |
| if (child.exitCode === 0) { | |
| editedText = await Bun.file(tmpFile).text(); | |
| } | |
| return editedText.trim().length > 0 ? editedText : null; | |
| } finally { | |
| // Clean up temp directory and its contents | |
| await Bun.$`rm -rf ${tmpDir}`; | |
| } | |
| } | |
| async function guessEditorDarwin(filePath: PathString): Promise<null | string[]> { | |
| // guess the editor based on current app (terminal inside one of these products) | |
| const bundleId = process.env.__CFBundleIdentifier; | |
| switch (bundleId) { | |
| case "com.todesktop.230313mzl4w4u92": | |
| return ["cursor", "--wait", filePath]; | |
| case "com.microsoft.VSCode": | |
| return ["code", "--wait", filePath]; | |
| case "com.microsoft.VSCodeInsiders": | |
| return ["code-insiders", "--wait", filePath]; | |
| case "com.exafunction.windsurf": | |
| return ["windsurf", "--wait", filePath]; | |
| default: | |
| return null; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment