11package readline
22
33import (
4+ "errors"
45 "fmt"
56 "os"
67 "os/exec"
@@ -15,6 +16,24 @@ const (
1516 windowsShell = "cmd"
1617)
1718
19+ func openInEditor (fd uintptr , termios any , content string ) (string , error ) {
20+ if err := UnsetRawMode (fd , termios ); err != nil {
21+ return content , err
22+ }
23+
24+ edited , err := runEditor (content )
25+
26+ if _ , restoreErr := SetRawMode (fd ); restoreErr != nil {
27+ return content , errors .Join (err , restoreErr )
28+ }
29+
30+ if err != nil {
31+ return content , err
32+ }
33+
34+ return edited , nil
35+ }
36+
1837func platformize (linux , windows string ) string {
1938 if runtime .GOOS == "windows" {
2039 return windows
@@ -24,7 +43,7 @@ func platformize(linux, windows string) string {
2443
2544func defaultEnvShell () []string {
2645 shell := os .Getenv ("SHELL" )
27- if len ( shell ) == 0 {
46+ if shell == "" {
2847 shell = platformize (defaultShell , windowsShell )
2948 }
3049 flag := "-c"
@@ -36,7 +55,7 @@ func defaultEnvShell() []string {
3655
3756func resolveEditor () ([]string , bool ) {
3857 editor := strings .TrimSpace (os .Getenv ("EDITOR" ))
39- if len ( editor ) == 0 {
58+ if editor == "" {
4059 editor = platformize (defaultEditor , windowsEditor )
4160 }
4261
@@ -57,12 +76,13 @@ func buildEditorCmd(filePath string) *exec.Cmd {
5776
5877 if shell {
5978 // The editor string is the last element — append the file path to it
60- args [len (args )- 1 ] = fmt .Sprintf ("%s '%s'" , args [len (args )- 1 ], filePath )
79+ safeFilePath := strings .ReplaceAll (filePath , "'" , "'\\ ''" )
80+ args [len (args )- 1 ] = fmt .Sprintf ("%s '%s'" , args [len (args )- 1 ], safeFilePath )
6181 } else {
6282 args = append (args , filePath )
6383 }
6484
65- cmd := exec .Command (args [0 ], args [1 :]... )
85+ cmd := exec .Command (args [0 ], args [1 :]... ) //nolint:gosec // $EDITOR is a user-controlled local env var, same trust model as git/kubectl
6686 cmd .Stdin = os .Stdin
6787 cmd .Stdout = os .Stdout
6888 cmd .Stderr = os .Stderr
@@ -76,7 +96,7 @@ func runEditor(content string) (string, error) {
7696 }
7797 defer os .Remove (tmpFile .Name ())
7898
79- if _ , err := tmpFile .Write ([] byte ( content ) ); err != nil {
99+ if _ , err := tmpFile .WriteString ( content ); err != nil {
80100 tmpFile .Close ()
81101 return content , err
82102 }
0 commit comments