editor.ts 1.1 KB

123456789101112131415161718192021222324252627282930313233
  1. import { defer } from "@/util/defer"
  2. import { rm } from "node:fs/promises"
  3. import { tmpdir } from "node:os"
  4. import { join } from "node:path"
  5. import { CliRenderer } from "@opentui/core"
  6. import { Filesystem } from "@/util/filesystem"
  7. import { Process } from "@/util/process"
  8. export namespace Editor {
  9. export async function open(opts: { value: string; renderer: CliRenderer }): Promise<string | undefined> {
  10. const editor = process.env["VISUAL"] || process.env["EDITOR"]
  11. if (!editor) return
  12. const filepath = join(tmpdir(), `${Date.now()}.md`)
  13. await using _ = defer(async () => rm(filepath, { force: true }))
  14. await Filesystem.write(filepath, opts.value)
  15. opts.renderer.suspend()
  16. opts.renderer.currentRenderBuffer.clear()
  17. const parts = editor.split(" ")
  18. const proc = Process.spawn([...parts, filepath], {
  19. stdin: "inherit",
  20. stdout: "inherit",
  21. stderr: "inherit",
  22. })
  23. await proc.exited
  24. const content = await Filesystem.readText(filepath)
  25. opts.renderer.currentRenderBuffer.clear()
  26. opts.renderer.resume()
  27. opts.renderer.requestRender()
  28. return content || undefined
  29. }
  30. }