1
1
use super :: {
2
2
textinput:: TextInputComponent , visibility_blocking,
3
3
CommandBlocking , CommandInfo , Component , DrawableComponent ,
4
+ ExternalEditorComponent ,
4
5
} ;
5
6
use crate :: {
7
+ get_app_config_path,
6
8
keys:: SharedKeyConfig ,
7
9
queue:: { InternalEvent , NeedsUpdate , Queue } ,
8
10
strings,
@@ -14,6 +16,11 @@ use asyncgit::{
14
16
CWD ,
15
17
} ;
16
18
use crossterm:: event:: Event ;
19
+ use std:: {
20
+ fs:: File ,
21
+ io:: { Read , Write } ,
22
+ path:: PathBuf ,
23
+ } ;
17
24
use tui:: { backend:: Backend , layout:: Rect , Frame } ;
18
25
19
26
pub struct RewordComponent {
@@ -51,6 +58,14 @@ impl Component for RewordComponent {
51
58
true ,
52
59
true ,
53
60
) ) ;
61
+
62
+ out. push ( CommandInfo :: new (
63
+ strings:: commands:: commit_open_editor (
64
+ & self . key_config ,
65
+ ) ,
66
+ true ,
67
+ true ,
68
+ ) ) ;
54
69
}
55
70
56
71
visibility_blocking ( self )
@@ -65,6 +80,11 @@ impl Component for RewordComponent {
65
80
if let Event :: Key ( e) = ev {
66
81
if e == self . key_config . enter {
67
82
self . reword ( )
83
+ } else if e == self . key_config . open_commit_editor {
84
+ self . queue . borrow_mut ( ) . push_back (
85
+ InternalEvent :: OpenExternalEditor ( None ) ,
86
+ ) ;
87
+ self . hide ( ) ;
68
88
}
69
89
70
90
return Ok ( true ) ;
@@ -121,6 +141,55 @@ impl RewordComponent {
121
141
Ok ( ( ) )
122
142
}
123
143
144
+ /// After an external editor has been open,
145
+ /// this should be called to put the text in the
146
+ /// right place
147
+ pub fn show_editor ( & mut self ) -> Result < ( ) > {
148
+ const COMMIT_MSG_FILE_NAME : & str = "COMMITMSG_EDITOR" ;
149
+ //TODO: use a tmpfile here
150
+ let mut config_path: PathBuf = get_app_config_path ( ) ?;
151
+ config_path. push ( COMMIT_MSG_FILE_NAME ) ;
152
+
153
+ {
154
+ let mut file = File :: create ( & config_path) ?;
155
+ file. write_fmt ( format_args ! (
156
+ "{}\n " ,
157
+ self . input. get_text( )
158
+ ) ) ?;
159
+ file. write_all (
160
+ strings:: commit_editor_msg ( & self . key_config )
161
+ . as_bytes ( ) ,
162
+ ) ?;
163
+ }
164
+
165
+ ExternalEditorComponent :: open_file_in_editor ( & config_path) ?;
166
+
167
+ let mut message = String :: new ( ) ;
168
+
169
+ let mut file = File :: open ( & config_path) ?;
170
+ file. read_to_string ( & mut message) ?;
171
+ drop ( file) ;
172
+ std:: fs:: remove_file ( & config_path) ?;
173
+
174
+ let message: String = message
175
+ . lines ( )
176
+ . flat_map ( |l| {
177
+ if l. starts_with ( '#' ) {
178
+ vec ! [ ]
179
+ } else {
180
+ vec ! [ l, "\n " ]
181
+ }
182
+ } )
183
+ . collect ( ) ;
184
+
185
+ let message = message. trim ( ) . to_string ( ) ;
186
+
187
+ self . input . set_text ( message) ;
188
+ self . input . show ( ) ?;
189
+
190
+ Ok ( ( ) )
191
+ }
192
+
124
193
///
125
194
pub fn reword ( & mut self ) {
126
195
if let Some ( commit_id) = self . commit_id {
0 commit comments