//go:build darwin package main import ( "bytes" "fmt" "os/exec" "strings" ) // "choose file name" is the standard NSSavePanel; it asks before replacing an // existing file. Text is passed via argv (no AppleScript string quoting). const saveDialogAS = `on run argv set nm to item 1 of argv set dir to item 2 of argv activate set f to choose file name with prompt "Save timestamped print as" default name nm default location (POSIX file dir) return POSIX path of f end run` func nativeSaveDialog(name, dir string) (string, bool, error) { cmd := exec.Command("/usr/bin/osascript", "-e", saveDialogAS, name, dir) var out, errb bytes.Buffer cmd.Stdout, cmd.Stderr = &out, &errb if err := cmd.Run(); err != nil { if strings.Contains(errb.String(), "-128") { // User canceled. return "", false, nil } return "", false, fmt.Errorf("%v: %s", err, strings.TrimSpace(errb.String())) } p := strings.TrimSpace(out.String()) if p == "" { return "", false, fmt.Errorf("empty path from dialog") } return p, true, nil }