Skip to content

Commit e6b6022

Browse files
committed
🎉 Add support for --amend
1 parent 81dbbb2 commit e6b6022

File tree

1 file changed

+40
-8
lines changed

1 file changed

+40
-8
lines changed

Diff for: ‎src/main.rs

+40-8
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ fn commit_type_at_index (index: u8) -> Option<CommitType> {
4242
CommitType::iter_variants().nth(index as usize)
4343
}
4444

45-
fn select_emoji() -> Option<&'static str> {
45+
fn select_emoji(initial_selected: Option<CommitType>) -> Option<&'static str> {
4646
let mut log_update = LogUpdate::new(stderr()).unwrap();
4747
let mut raw_output = stderr().into_raw_mode().unwrap();
4848

4949
let mut key_stream = stdin().keys();
5050

5151
let mut aborted = false;
52-
let mut selected = CommitType::Breaking;
52+
let mut selected = initial_selected.unwrap_or(CommitType::Breaking);
5353

5454
// Clear possibly printed "hint" from git
5555
log_update.render("").unwrap();
@@ -73,14 +73,14 @@ fn select_emoji() -> Option<&'static str> {
7373
if aborted { None } else { Some(selected.emoji()) }
7474
}
7575

76-
fn collect_commit_message(selected_emoji: &'static str, launch_editor: &mut bool) -> Option<String> {
76+
fn collect_commit_message(selected_emoji: &'static str, initial_message: Option<String>, launch_editor: &mut bool) -> Option<String> {
7777
let mut log_update = LogUpdate::new(stderr()).unwrap();
7878
let mut raw_output = stderr().into_raw_mode().unwrap();
7979

8080
let mut key_stream = stdin().keys();
8181

8282
let mut aborted = false;
83-
let mut input = String::new();
83+
let mut input = initial_message.unwrap_or(String::new());
8484

8585
loop {
8686
let rule_text = commit_rules::check_message(&input)
@@ -143,6 +143,30 @@ fn launch_git_with_self_as_editor() {
143143
run_cmd(Command::new("git").arg("commit").env("GIT_EDITOR", self_path))
144144
}
145145

146+
fn git_parse_existing_message(file: &mut File) -> Option<(CommitType, String)> {
147+
let first_line = file.read_line().unwrap().unwrap();
148+
149+
if first_line.is_empty() {
150+
return None;
151+
}
152+
153+
154+
let first_str = first_line.chars().next().unwrap().to_string();
155+
156+
let commit_type = CommitType::iter_variants().find(|commit_type| {
157+
first_str == commit_type.emoji()
158+
});
159+
160+
if commit_type == None { return None; }
161+
162+
// Check that the rest of the commit message is empty (i.e. no body)
163+
if !git_message_is_empty(file) { return None; }
164+
165+
let emoji = commit_type.unwrap().emoji().to_string();
166+
let message = first_line.replace(&emoji, "").trim().to_string();
167+
Some((commit_type.unwrap(), message))
168+
}
169+
146170
fn git_message_is_empty(file: &mut File) -> bool {
147171
for line in BufReader::new(file).lines() {
148172
let line = line.expect("Failed to read line from git message file");
@@ -156,20 +180,28 @@ fn git_message_is_empty(file: &mut File) -> bool {
156180

157181
fn collect_information_and_write_to_file(out_path: PathBuf) {
158182
let mut file = File::options().read(true).write(true).create(true).open(&out_path).unwrap();
183+
let mut initial_message: Option<String> = None;
184+
let mut initial_commit_type: Option<CommitType> = None;
159185

160186
if !git_message_is_empty(&mut file) {
161-
launch_default_editor(out_path);
162-
return;
187+
file.rewind().unwrap();
188+
if let Some((commit_type, message)) = git_parse_existing_message(&mut file) {
189+
initial_commit_type = Some(commit_type);
190+
initial_message = Some(message);
191+
} else {
192+
launch_default_editor(out_path);
193+
return;
194+
}
163195
}
164196

165-
let maybe_emoji = select_emoji();
197+
let maybe_emoji = select_emoji(initial_commit_type);
166198
if maybe_emoji == None {
167199
abort();
168200
}
169201

170202
if let Some(emoji) = maybe_emoji {
171203
let mut launch_editor = false;
172-
let maybe_message = collect_commit_message(emoji, &mut launch_editor);
204+
let maybe_message = collect_commit_message(emoji, initial_message, &mut launch_editor);
173205
if maybe_message == None {
174206
abort();
175207
}

0 commit comments

Comments
 (0)