imap-notes/lib/openers.go

92 lines
1.8 KiB
Go

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
}