summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2021-08-22 22:43:11 -0700
committerDan Davison <dandavison7@gmail.com>2021-08-22 23:57:09 -0700
commit7293eca8b8384922927411604c1b5ea53e3468da (patch)
tree78b31c14e66a701dae195550cbb77fae2f506a9d
parente2dbcd12b4c934a18e7ee3b8f983be4a42c0b318 (diff)
WIP
-rw-r--r--Cargo.lock33
-rw-r--r--Cargo.toml2
-rw-r--r--src/delta.rs21
-rw-r--r--src/parse.rs73
4 files changed, 127 insertions, 2 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2c115db1..dc970c6f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -145,8 +145,20 @@ version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
+ "libc",
"num-integer",
"num-traits",
+ "time",
+ "winapi",
+]
+
+[[package]]
+name = "chrono-humanize"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2eddc119501d583fd930cb92144e605f44e0252c38dd89d9247fffa1993375cb"
+dependencies = [
+ "chrono",
]
[[package]]
@@ -276,7 +288,7 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if 1.0.0",
"libc",
- "wasi",
+ "wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
@@ -289,6 +301,8 @@ dependencies = [
"bitflags",
"box_drawing",
"bytelines",
+ "chrono",
+ "chrono-humanize",
"console",
"ctrlc",
"dirs-next",
@@ -834,6 +848,17 @@ dependencies = [
]
[[package]]
+name = "time"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
+dependencies = [
+ "libc",
+ "wasi 0.10.0+wasi-snapshot-preview1",
+ "winapi",
+]
+
+[[package]]
name = "tinyvec"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -959,6 +984,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
+[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 8a960b3e..8de22eb4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,6 +15,8 @@ name = "delta"
path = "src/main.rs"
[dependencies]
+chrono = "0.4.19"
+chrono-humanize = "0.2.1"
ansi_colours = "1.0.4"
ansi_term = "0.12.1"
atty = "0.2.14"
diff --git a/src/delta.rs b/src/delta.rs
index e0a1e1c2..c9f23458 100644
--- a/src/delta.rs
+++ b/src/delta.rs
@@ -126,7 +126,8 @@ impl<'a> StateMachine<'a> {
|| self.handle_additional_file_meta_cases()?
|| self.handle_submodule_log_line()?
|| self.handle_submodule_short_line()?
- || self.handle_hunk_line()?;
+ || self.handle_hunk_line()?
+ || self.handle_blame_line()?;
if self.state == State::FileMeta && self.should_handle() && !self.config.color_only {
// Skip file metadata lines unless a raw diff style has been requested.
@@ -463,6 +464,24 @@ impl<'a> StateMachine<'a> {
Ok(true)
}
+ fn handle_blame_line(&mut self) -> std::io::Result<bool> {
+ let mut handled_line = false;
+ if let Some(blame) = parse::parse_git_blame_line(&self.line) {
+ writeln!(
+ self.painter.writer,
+ "{}: {} {} {}",
+ self.config.commit_style.paint(blame.commit),
+ blame.author,
+ chrono_humanize::HumanTime::from(blame.time),
+ // highlighter.highlight(&line[1..], &config.syntax_set);
+ blame.code,
+ )?;
+
+ handled_line = true
+ }
+ Ok(handled_line)
+ }
+
fn _handle_additional_cases(&mut self, to_state: State) -> std::io::Result<bool> {
let mut handled_line = false;
diff --git a/src/parse.rs b/src/parse.rs
index c6a0860f..31524536 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -4,6 +4,8 @@ use std::borrow::Cow;
use std::path::Path;
use unicode_segmentation::UnicodeSegmentation;
+use chrono::{DateTime, FixedOffset};
+
use crate::config::Config;
use crate::features;
@@ -280,6 +282,77 @@ pub fn get_submodule_short_commit(line: &str) -> Option<&str> {
}
}
+pub struct BlameLine<'a> {
+ pub commit: &'a str,
+ pub author: &'a str,
+ pub time: DateTime<FixedOffset>,
+ pub line_number: usize,
+ pub code: &'a str,
+}
+
+// E.g.
+//ea82f2d0 (Dan Davison 2021-08-22 18:20:19 -0700 120) let mut handled_line = self.handle_commit_meta_header_line()?
+
+lazy_static! {
+ static ref BLAME_LINE_REGEX: Regex = Regex::new(
+ r"(?x)
+^
+(
+ [0-9a-f]{8} # commit hash
+)
+[\ ]
+\( # open (
+(
+ [^\ ].* # author name
+)
+[\ ]+
+( # timestamp
+ [0-9]{4}-[01][0-9]-[0123][0-9] [012][0-9]:[0-5][0-9]:[0-5][0-9] [-+][0-9]{4}
+)
+[\ ]
+(
+ [0-9]+ # line number
+)
+\) # close )
+[\ ]
+(
+ .* # code
+)
+"
+ )
+ .unwrap();
+}
+
+pub fn parse_git_blame_line(line: &str) -> Option<BlameLine> {
+ if let Some(caps) = BLAME_LINE_REGEX.captures(line) {
+ let commit = caps.get(1).unwrap().as_str();
+ let author = caps.get(2).unwrap().as_str();
+ let timestamp = caps.get(3).unwrap().as_str();
+ if let Ok(time) = DateTime::parse_from_str(timestamp, "%Y-%m-%d %H:%M:%S %z") {
+ let line_number_str = caps.get(4).unwrap().as_str();
+ if let Ok(line_number) = line_number_str.parse::<usize>() {
+ let code = caps.get(5).unwrap().as_str();
+ Some(BlameLine {
+ commit,
+ author,
+ time,
+ line_number,
+ code,
+ })
+ } else {
+ eprintln!("Failed to parse line number: {}", line_number_str);
+ None
+ }
+ } else {
+ eprintln!("Failed to parse timestamp: {}", timestamp);
+ None
+ }
+ } else {
+ eprintln!("Failed to match:\n{}", line);
+ None
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;