1package macos
2
3import (
4 _ "embed"
5 "fmt"
6 "os"
7 "os/exec"
8 "path/filepath"
9 "runtime"
10 "strings"
11)
12
13//go:embed file_picker.swift
14var filePickerSwift string
15
16// OpenFilePicker launches the native macOS file picker.
17// It returns a list of selected absolute file paths.
18func OpenFilePicker(initialPath string) ([]string, error) {
19 if runtime.GOOS != "darwin" {
20 return nil, fmt.Errorf("OpenFilePicker is only supported on macOS")
21 }
22
23 tmpDir, err := os.MkdirTemp("", "matcha-filepicker")
24 if err != nil {
25 return nil, err
26 }
27 defer os.RemoveAll(tmpDir) //nolint:errcheck
28
29 swiftFile := filepath.Join(tmpDir, "file_picker.swift")
30 if err := os.WriteFile(swiftFile, []byte(filePickerSwift), 0644); err != nil {
31 return nil, err
32 }
33
34 binFile := filepath.Join(tmpDir, "file_picker")
35
36 // Compile
37 cmd := exec.Command("swiftc", swiftFile, "-o", binFile) //nolint:noctx
38 if out, err := cmd.CombinedOutput(); err != nil {
39 return nil, fmt.Errorf("failed to compile file picker helper: %w\n%s", err, string(out))
40 }
41
42 // Run
43 args := []string{}
44 if initialPath != "" {
45 args = append(args, initialPath)
46 }
47 out, err := exec.Command(binFile, args...).Output() //nolint:noctx
48 if err != nil {
49 // Exit code 1 usually means user cancelled
50 return nil, nil
51 }
52
53 trimmed := strings.TrimSpace(string(out))
54 if trimmed == "" {
55 return nil, nil
56 }
57
58 paths := strings.Split(trimmed, "\n")
59 return paths, nil
60}