mirror of
https://github.com/la5nta/pat
synced 2026-08-07 22:32:06 -04:00
68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
package editor
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/la5nta/pat/internal/buildinfo"
|
|
)
|
|
|
|
func Executable() string {
|
|
if e := os.Getenv("EDITOR"); e != "" {
|
|
return e
|
|
} else if e := os.Getenv("VISUAL"); e != "" {
|
|
return e
|
|
}
|
|
|
|
switch runtime.GOOS {
|
|
case "windows":
|
|
return "notepad"
|
|
case "linux":
|
|
if path, err := exec.LookPath("editor"); err == nil {
|
|
return path
|
|
}
|
|
}
|
|
|
|
return "vi"
|
|
}
|
|
|
|
func Open(path string) error {
|
|
cmd := exec.Command(Executable(), path)
|
|
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
|
return cmd.Run()
|
|
}
|
|
|
|
func EditText(template string) (string, error) {
|
|
f, err := os.CreateTemp("", strings.ToLower(buildinfo.AppName)+"_edit_*.txt")
|
|
if err != nil {
|
|
return template, fmt.Errorf("Unable to prepare temporary file for body: %w", err)
|
|
}
|
|
defer f.Close()
|
|
defer os.Remove(f.Name())
|
|
|
|
f.Write([]byte(template))
|
|
f.Sync()
|
|
|
|
// Windows fix: Avoid 'cannot access the file because it is being used by another process' error.
|
|
// Close the file before opening the editor.
|
|
f.Close()
|
|
|
|
// Fire up the editor
|
|
if err := Open(f.Name()); err != nil {
|
|
return template, fmt.Errorf("Unable to start text editor: %w", err)
|
|
}
|
|
|
|
// Read back the edited file
|
|
f, err = os.OpenFile(f.Name(), os.O_RDWR, 0o666)
|
|
if err != nil {
|
|
return template, fmt.Errorf("Unable to read temporary file from editor: %w", err)
|
|
}
|
|
defer f.Close()
|
|
defer os.Remove(f.Name())
|
|
body, err := io.ReadAll(f)
|
|
return string(body), err
|
|
}
|