package lib import ( "fmt" "io/ioutil" "os" "os/exec" "strings" ) const ( DefaultEditor = "nano" DefaultShell = "sh" DefaultPager = "less" ) func getEditor() string { editor := os.Getenv("EDITOR") if editor == "" { editor = DefaultEditor } return editor } func getShell() string { shell := os.Getenv("SHELL") if shell == "" { shell = DefaultShell } return shell } func getPager() string { return DefaultPager } // OpenInEditor opens the passed body text in an editor and returns it after. func OpenInEditor(body string) (string, error) { tmpfile, err := ioutil.TempFile("", "imap-note-*.md") if err != nil { return "", fmt.Errorf("failed to create tempfile: %w", err) } // Cleanup on exit defer os.Remove(tmpfile.Name()) if _, err = tmpfile.WriteString(body); err != nil { return "", fmt.Errorf("failed to write note to tempfile: %w", err) } if err = tmpfile.Close(); err != nil { return "", fmt.Errorf("failed to close file after writing original content: %w", err) } editor := getEditor() shell := getShell() cmd := exec.Command(shell, "-c", editor+" "+tmpfile.Name()) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { return "", fmt.Errorf("failed running editor command: %w", err) } newBytes, err := os.ReadFile(tmpfile.Name()) if err != nil { return "", fmt.Errorf("failed to read new contents from tmp file: %w", err) } return string(newBytes), nil } // OpenInPager opens the passed body text in a pager. func OpenInPager(body string) error { pager := getPager() cmd := exec.Command(pager) cmd.Stdin = strings.NewReader(body) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("failed to run pager: %w", err) } return nil }