package tui import ( "context" "os" "os/exec" tea "github.com/charmbracelet/bubbletea" "git.unkin.net/unkin/forgebot/pkg/models" ) type editorFinishedMsg struct { err error } func editTaskCmd(task *models.Task, client *Client) tea.Cmd { data := marshalTaskForEdit(task) tmpFile, err := os.CreateTemp("", "forgebot-task-*.yaml") if err != nil { return func() tea.Msg { return editorFinishedMsg{err: err} } } tmpPath := tmpFile.Name() if _, err := tmpFile.Write(data); err != nil { tmpFile.Close() os.Remove(tmpPath) return func() tea.Msg { return editorFinishedMsg{err: err} } } tmpFile.Close() editor := resolveEditor() c := exec.Command(editor, tmpPath) return tea.ExecProcess(c, func(err error) tea.Msg { defer os.Remove(tmpPath) if err != nil { return editorFinishedMsg{err: err} } edited, err := os.ReadFile(tmpPath) if err != nil { return editorFinishedMsg{err: err} } et, err := unmarshalEditedTask(edited) if err != nil { return editorFinishedMsg{err: err} } diff := diffEditableTask(task, et) if diff == nil { return editorFinishedMsg{} } err = client.UpdateTask(context.Background(), task.ID, *diff) return editorFinishedMsg{err: err} }) } func newTaskEditorCmd(client *Client) tea.Cmd { data := marshalNewTask() tmpFile, err := os.CreateTemp("", "forgebot-new-*.yaml") if err != nil { return func() tea.Msg { return editorFinishedMsg{err: err} } } tmpPath := tmpFile.Name() if _, err := tmpFile.Write(data); err != nil { tmpFile.Close() os.Remove(tmpPath) return func() tea.Msg { return editorFinishedMsg{err: err} } } tmpFile.Close() editor := resolveEditor() c := exec.Command(editor, tmpPath) return tea.ExecProcess(c, func(err error) tea.Msg { defer os.Remove(tmpPath) if err != nil { return editorFinishedMsg{err: err} } edited, err := os.ReadFile(tmpPath) if err != nil { return editorFinishedMsg{err: err} } req, err := unmarshalNewTask(edited) if err != nil { return editorFinishedMsg{err: err} } _, err = client.CreateTask(context.Background(), *req) return editorFinishedMsg{err: err} }) } func resolveEditor() string { if e := os.Getenv("EDITOR"); e != "" { return e } if e := os.Getenv("VISUAL"); e != "" { return e } return "vi" }