Skip to content

Commit 17c56a1

Browse files
committed
Allow opening external editor to edit reword
1 parent 5155245 commit 17c56a1

File tree

2 files changed

+91
-2
lines changed

2 files changed

+91
-2
lines changed

src/app.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ use tui::{
3333
Frame,
3434
};
3535

36+
/// Used to determine where the user should
37+
/// be put when the external editor is closed
38+
pub enum EditorVisible {
39+
Commit,
40+
Reword,
41+
}
42+
3643
///
3744
pub struct App {
3845
do_quit: bool,
@@ -59,6 +66,7 @@ pub struct App {
5966
theme: SharedTheme,
6067
key_config: SharedKeyConfig,
6168
input: Input,
69+
cur_editor_visible: EditorVisible,
6270

6371
// "Flags"
6472
requires_redraw: Cell<bool>,
@@ -175,6 +183,7 @@ impl App {
175183
key_config,
176184
requires_redraw: Cell::new(false),
177185
file_to_open: None,
186+
cur_editor_visible: EditorVisible::Commit,
178187
}
179188
}
180189

@@ -263,7 +272,14 @@ impl App {
263272
Path::new(&path),
264273
)
265274
}
266-
None => self.commit.show_editor(),
275+
None => match self.cur_editor_visible {
276+
EditorVisible::Commit => {
277+
self.commit.show_editor()
278+
}
279+
EditorVisible::Reword => {
280+
self.reword_popup.show_editor()
281+
}
282+
},
267283
};
268284

269285
if let Err(e) = result {
@@ -513,7 +529,10 @@ impl App {
513529
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
514530
}
515531
InternalEvent::Update(u) => flags.insert(u),
516-
InternalEvent::OpenCommit => self.commit.show()?,
532+
InternalEvent::OpenCommit => {
533+
self.cur_editor_visible = EditorVisible::Commit;
534+
self.commit.show()?;
535+
}
517536
InternalEvent::PopupStashing(opts) => {
518537
self.stashmsg_popup.options(opts);
519538
self.stashmsg_popup.show()?
@@ -522,6 +541,7 @@ impl App {
522541
self.tag_commit_popup.open(id)?;
523542
}
524543
InternalEvent::RewordCommit(id) => {
544+
self.cur_editor_visible = EditorVisible::Reword;
525545
self.reword_popup.open(id)?;
526546
}
527547
InternalEvent::CreateBranch => {

src/components/reword.rs

+69
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use super::{
22
textinput::TextInputComponent, visibility_blocking,
33
CommandBlocking, CommandInfo, Component, DrawableComponent,
4+
ExternalEditorComponent,
45
};
56
use crate::{
7+
get_app_config_path,
68
keys::SharedKeyConfig,
79
queue::{InternalEvent, NeedsUpdate, Queue},
810
strings,
@@ -14,6 +16,11 @@ use asyncgit::{
1416
CWD,
1517
};
1618
use crossterm::event::Event;
19+
use std::{
20+
fs::File,
21+
io::{Read, Write},
22+
path::PathBuf,
23+
};
1724
use tui::{backend::Backend, layout::Rect, Frame};
1825

1926
pub struct RewordComponent {
@@ -51,6 +58,14 @@ impl Component for RewordComponent {
5158
true,
5259
true,
5360
));
61+
62+
out.push(CommandInfo::new(
63+
strings::commands::commit_open_editor(
64+
&self.key_config,
65+
),
66+
true,
67+
true,
68+
));
5469
}
5570

5671
visibility_blocking(self)
@@ -65,6 +80,11 @@ impl Component for RewordComponent {
6580
if let Event::Key(e) = ev {
6681
if e == self.key_config.enter {
6782
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();
6888
}
6989

7090
return Ok(true);
@@ -121,6 +141,55 @@ impl RewordComponent {
121141
Ok(())
122142
}
123143

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+
124193
///
125194
pub fn reword(&mut self) {
126195
if let Some(commit_id) = self.commit_id {

0 commit comments

Comments
 (0)