diff options
Diffstat (limited to 'src/delta.rs')
-rw-r--r-- | src/delta.rs | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/src/delta.rs b/src/delta.rs index c42ba9f1..fca76ff8 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -18,13 +18,14 @@ use crate::style::{self, DecorationStyle}; #[derive(Clone, Debug, PartialEq)] pub enum State { - CommitMeta, // In commit metadata section + CommitMeta, // In commit metadata section FileMeta, // In diff metadata section, between (possible) commit metadata and first hunk - HunkHeader, // In hunk metadata line + HunkHeader(String, String), // In hunk metadata line (line, raw_line) HunkZero, // In hunk; unchanged line HunkMinus(Option<String>), // In hunk; removed line (raw_line) HunkPlus(Option<String>), // In hunk; added line (raw_line) - Submodule, + SubmoduleLog, // In a submodule section, with gitconfig diff.submodule = log + SubmoduleShort(String), // In a submodule section, with gitconfig diff.submodule = short Unknown, } @@ -39,7 +40,7 @@ impl State { fn is_in_hunk(&self) -> bool { matches!( *self, - State::HunkHeader | State::HunkZero | State::HunkMinus(_) | State::HunkPlus(_) + State::HunkHeader(_, _) | State::HunkZero | State::HunkMinus(_) | State::HunkPlus(_) ) } } @@ -145,7 +146,13 @@ impl<'a> StateMachine<'a> { { self.handle_additional_cases(State::FileMeta)? } else if line.starts_with("Submodule ") { - self.handle_additional_cases(State::Submodule)? + self.handle_additional_cases(State::SubmoduleLog)? + } else if (matches!(self.state, State::HunkHeader(_, _)) + && line.starts_with("-Subproject commit ")) + || (matches!(self.state, State::SubmoduleShort(_)) + && line.starts_with("+Subproject commit ")) + { + self.handle_submodule_short_line()? } else if self.state.is_in_hunk() { // A true hunk line should start with one of: '+', '-', ' '. However, handle_hunk_line // handles all lines until the state transitions away from the hunk states. @@ -415,14 +422,39 @@ impl<'a> StateMachine<'a> { Ok(handled_line) } - /// Emit the hunk header, with any requested decoration. + fn handle_submodule_short_line(&mut self) -> std::io::Result<bool> { + if let Some(commit) = parse::get_submodule_short_commit(&self.line) { + if let State::HunkHeader(_, _) = self.state { + self.state = State::SubmoduleShort(commit.to_owned()); + } else if let State::SubmoduleShort(minus_commit) = &self.state { + self.painter.emit()?; + writeln!( + self.painter.writer, + "{} ⟶ {}", + self.config + .minus_style + .paint(minus_commit.chars().take(7).collect::<String>()), + self.config + .plus_style + .paint(commit.chars().take(7).collect::<String>()), + )?; + } + } + Ok(true) + } + fn handle_hunk_header_line(&mut self) -> std::io::Result<bool> { + self.state = State::HunkHeader(self.line.clone(), self.raw_line.clone()); + Ok(true) + } + + /// Emit the hunk header, with any requested decoration. + fn emit_hunk_header_line(&mut self, line: &str, raw_line: &str) -> std::io::Result<bool> { self.painter.paint_buffered_minus_and_plus_lines(); - self.state = State::HunkHeader; self.painter.set_highlighter(); self.painter.emit()?; - let (code_fragment, line_numbers) = parse::parse_hunk_header(&self.line); + let (code_fragment, line_numbers) = parse::parse_hunk_header(line); if self.config.line_numbers { self.painter .line_numbers_data @@ -430,12 +462,7 @@ impl<'a> StateMachine<'a> { } if self.config.hunk_header_style.is_raw { - hunk_header::write_hunk_header_raw( - &mut self.painter, - &self.line, - &self.raw_line, - self.config, - )?; + hunk_header::write_hunk_header_raw(&mut self.painter, line, raw_line, self.config)?; } else if self.config.hunk_header_style.is_omitted { writeln!(self.painter.writer)?; } else { @@ -449,7 +476,7 @@ impl<'a> StateMachine<'a> { &code_fragment, &line_numbers, &mut self.painter, - &self.line, + line, &self.plus_file, self.config, )?; @@ -473,6 +500,9 @@ impl<'a> StateMachine<'a> { { self.painter.paint_buffered_minus_and_plus_lines(); } + if let State::HunkHeader(line, raw_line) = &self.state.clone() { + self.emit_hunk_header_line(line, raw_line)?; + } self.state = match self.line.chars().next() { Some('-') => { if let State::HunkPlus(_) = self.state { |