11package readline
22
33import (
4+ "fmt"
45 "os"
56 "os/exec"
67 "runtime"
78 "strings"
89)
910
10- func runEditor (content string , defaultEditor string ) (string , error ) {
11+ const (
12+ defaultEditor = "vi"
13+ defaultShell = "/bin/bash"
14+ windowsEditor = "notepad"
15+ windowsShell = "cmd"
16+ )
17+
18+ func platformize (linux , windows string ) string {
19+ if runtime .GOOS == "windows" {
20+ return windows
21+ }
22+ return linux
23+ }
24+
25+ func defaultEnvShell () []string {
26+ shell := os .Getenv ("SHELL" )
27+ if len (shell ) == 0 {
28+ shell = platformize (defaultShell , windowsShell )
29+ }
30+ flag := "-c"
31+ if shell == windowsShell {
32+ flag = "/C"
33+ }
34+ return []string {shell , flag }
35+ }
36+
37+ func resolveEditor () ([]string , bool ) {
38+ editor := strings .TrimSpace (os .Getenv ("EDITOR" ))
39+ if len (editor ) == 0 {
40+ editor = platformize (defaultEditor , windowsEditor )
41+ }
42+
43+ if ! strings .Contains (editor , " " ) {
44+ return []string {editor }, false
45+ }
46+
47+ if ! strings .ContainsAny (editor , "\" '\\ " ) {
48+ return strings .Split (editor , " " ), false
49+ }
50+
51+ shell := defaultEnvShell ()
52+ return append (shell , editor ), true
53+ }
54+
55+ func buildEditorCmd (filePath string ) * exec.Cmd {
56+ args , shell := resolveEditor ()
57+
58+ if shell {
59+ // The editor string is the last element — append the file path to it
60+ // so the shell interprets the full command.
61+ args [len (args )- 1 ] = fmt .Sprintf ("%s %s" , args [len (args )- 1 ], filePath )
62+ } else {
63+ args = append (args , filePath )
64+ }
65+
66+ cmd := exec .Command (args [0 ], args [1 :]... )
67+ cmd .Stdin = os .Stdin
68+ cmd .Stdout = os .Stdout
69+ cmd .Stderr = os .Stderr
70+ return cmd
71+ }
72+
73+ func runEditor (content string ) (string , error ) {
1174 tmpFile , err := os .CreateTemp ("" , "docker-model-prompt-*.txt" )
1275 if err != nil {
1376 return content , err
@@ -20,7 +83,7 @@ func runEditor(content string, defaultEditor string) (string, error) {
2083 }
2184 tmpFile .Close ()
2285
23- cmd := buildEditorCmd (defaultEditor , tmpFile .Name ())
86+ cmd := buildEditorCmd (tmpFile .Name ())
2487 if err := cmd .Run (); err != nil {
2588 return content , err
2689 }
@@ -30,25 +93,5 @@ func runEditor(content string, defaultEditor string) (string, error) {
3093 return content , err
3194 }
3295
33- result := strings .TrimRight (string (edited ), "\r \n " )
34-
35- return result , nil
36- }
37-
38- func buildEditorCmd (defaultEditor string , filePath string ) * exec.Cmd {
39- editor := strings .TrimSpace (os .Getenv ("EDITOR" ))
40- if editor == "" {
41- editor = defaultEditor
42- }
43-
44- var cmd * exec.Cmd
45- if runtime .GOOS == "windows" {
46- cmd = exec .Command ("cmd" , "/C" , editor + " \" " + filePath + "\" " )
47- } else {
48- cmd = exec .Command ("sh" , "-c" , editor + " \" $1\" " , "--" , filePath )
49- }
50- cmd .Stdin = os .Stdin
51- cmd .Stdout = os .Stdout
52- cmd .Stderr = os .Stderr
53- return cmd
96+ return strings .TrimRight (string (edited ), "\r \n " ), nil
5497}
0 commit comments