1
1
use std:: {
2
- env, fs,
2
+ env,
3
+ fs:: { self , File } ,
3
4
io:: { stdin, Cursor , IsTerminal , Write } ,
4
5
path:: PathBuf ,
5
- process:: { self , Stdio } ,
6
+ process:: { self } ,
6
7
} ;
7
8
9
+ #[ cfg( windows) ]
10
+ use std:: process:: Stdio ;
11
+
8
12
use base64:: { engine:: general_purpose:: STANDARD as BASE64 , Engine as _} ;
9
13
use stellar_xdr:: curr;
10
14
@@ -63,7 +67,9 @@ impl Cmd {
63
67
} ;
64
68
65
69
let path = tmp_file ( & json) ?;
66
- open_editor ( & print, & path) ?;
70
+ let editor = get_editor ( ) ;
71
+
72
+ open_editor ( & print, & editor, & path) ?;
67
73
68
74
let contents = fs:: read_to_string ( & path) ?;
69
75
let xdr = json_to_xdr :: < curr:: TransactionEnvelope > ( & contents) ?;
@@ -75,8 +81,14 @@ impl Cmd {
75
81
}
76
82
}
77
83
84
+ struct Editor {
85
+ cmd : String ,
86
+ source : String ,
87
+ args : Vec < String > ,
88
+ }
89
+
78
90
fn tmp_file ( contents : & str ) -> Result < PathBuf , Error > {
79
- let temp_dir = env:: temp_dir ( ) ;
91
+ let temp_dir = env:: current_dir ( ) . unwrap_or ( env :: temp_dir ( ) ) ;
80
92
let file_name = format ! ( "stellar-json-xdr-{}.json" , rand:: random:: <u64 >( ) ) ;
81
93
let path = temp_dir. join ( file_name) ;
82
94
@@ -86,31 +98,58 @@ fn tmp_file(contents: &str) -> Result<PathBuf, Error> {
86
98
Ok ( path)
87
99
}
88
100
89
- fn get_editor ( ) -> String {
90
- env:: var ( "STELLAR_EDITOR" )
91
- . or_else ( |_| env:: var ( "EDITOR" ) )
92
- . or_else ( |_| env:: var ( "VISUAL" ) )
93
- . unwrap_or_else ( |_| "vi" . to_string ( ) )
101
+ fn get_editor ( ) -> Editor {
102
+ let ( source, cmd) = env:: var ( "STELLAR_EDITOR" )
103
+ . map ( |val| ( "STELLAR_EDITOR" , val) )
104
+ . or_else ( |_| env:: var ( "EDITOR" ) . map ( |val| ( "EDITOR" , val) ) )
105
+ . or_else ( |_| env:: var ( "VISUAL" ) . map ( |val| ( "VISUAL" , val) ) )
106
+ . unwrap_or_else ( |_| ( "default" , "vim" . to_string ( ) ) ) ;
107
+
108
+ let parts: Vec < & str > = cmd. split_whitespace ( ) . collect ( ) ;
109
+ let cmd = parts[ 0 ] . to_string ( ) ;
110
+ let args = & parts[ 1 ..]
111
+ . iter ( )
112
+ . map ( |& s| s. to_string ( ) )
113
+ . collect :: < Vec < String > > ( ) ;
114
+
115
+ Editor {
116
+ source : source. to_string ( ) ,
117
+ cmd,
118
+ args : args. clone ( ) ,
119
+ }
94
120
}
95
121
96
- fn open_editor ( print : & Print , path : & PathBuf ) -> Result < ( ) , Error > {
97
- let editor = get_editor ( ) ;
98
- print. infoln ( format ! ( "Using `{editor}`" ) ) ;
122
+ fn open_editor ( print : & Print , editor : & Editor , path : & PathBuf ) -> Result < ( ) , Error > {
123
+ print. infoln ( format ! (
124
+ "Using `{source}=\" {cmd}\" `" ,
125
+ source = editor. source,
126
+ cmd = editor. cmd,
127
+ ) ) ;
99
128
100
- let parts: Vec < & str > = editor. split_whitespace ( ) . collect ( ) ;
101
- let cmd = parts[ 0 ] ;
102
- let args = & parts[ 1 ..] ;
129
+ print. infoln ( "Opening editor..." . to_string ( ) ) ;
103
130
104
- print. infoln ( "Opening editor to edit the transaction envelope..." . to_string ( ) ) ;
131
+ let mut binding = process:: Command :: new ( editor. cmd . clone ( ) ) ;
132
+ let command = binding. args ( editor. args . clone ( ) ) . arg ( path) ;
133
+
134
+ #[ cfg( windows) ]
135
+ let tty = Stdio :: null ( ) ;
136
+
137
+ #[ cfg( unix) ]
138
+ {
139
+ let tty = File :: open ( "/dev/tty" ) ?;
140
+ let tty_out = fs:: OpenOptions :: new ( ) . write ( true ) . open ( "/dev/tty" ) ?;
141
+ let tty_err = fs:: OpenOptions :: new ( ) . write ( true ) . open ( "/dev/tty" ) ?;
142
+
143
+ command
144
+ . stdin ( tty)
145
+ . stdout ( tty_out)
146
+ . stderr ( tty_err)
147
+ . env ( "TERM" , "xterm-256color" ) ;
148
+ }
105
149
106
- let result = process:: Command :: new ( cmd)
107
- . stdin ( Stdio :: null ( ) )
108
- . args ( args)
109
- . arg ( path)
110
- . spawn ( ) ?
111
- . wait_with_output ( ) ?;
150
+ let status = command. spawn ( ) ?. wait ( ) ?;
112
151
113
- if result . status . success ( ) {
152
+ if status. success ( ) {
114
153
Ok ( ( ) )
115
154
} else {
116
155
Err ( Error :: EditorNonZeroStatus )
0 commit comments