forked from kemitix/git-next
feat(tui): highlight branchs in log
This commit is contained in:
parent
1df982005e
commit
01f54d79ae
1 changed files with 86 additions and 2 deletions
|
@ -1,9 +1,13 @@
|
|||
//
|
||||
use git_next_core::git::graph::Log;
|
||||
use lazy_static::lazy_static;
|
||||
use ratatui::{
|
||||
text::{Line, Text},
|
||||
style::{Color, Style, Styled as _},
|
||||
text::{Line, Span, Text},
|
||||
widgets::{Paragraph, Widget},
|
||||
};
|
||||
use regex::Regex;
|
||||
use tracing::info;
|
||||
|
||||
use super::HeightContraintLength;
|
||||
|
||||
|
@ -39,8 +43,88 @@ impl LogLine {
|
|||
Self { raw: raw.into() }
|
||||
}
|
||||
}
|
||||
lazy_static::lazy_static! {
|
||||
static ref RE: Regex =
|
||||
#[allow(clippy::unwrap_used)]
|
||||
Regex::new(
|
||||
r"^(?<pre>.*)\s(?<hash>[0-9a-f]{7})\s\((?<branches>.*?)\)\s(?<message>.*)",
|
||||
).unwrap();
|
||||
|
||||
static ref BRANCHES: Regex =
|
||||
#[allow(clippy::unwrap_used)]
|
||||
Regex::new(
|
||||
r"origin\/(?<branch>[^,]+)",
|
||||
).unwrap();
|
||||
}
|
||||
impl From<LogLine> for Line<'_> {
|
||||
fn from(value: LogLine) -> Self {
|
||||
Line::from(value.raw)
|
||||
if let Some(caps) = RE.captures(&value.raw) {
|
||||
let pre = caps["pre"].to_owned();
|
||||
let hash = caps["hash"].to_owned();
|
||||
let message = caps["message"].to_owned();
|
||||
info!(branches=?caps["branches"], "raw branches");
|
||||
let mut branches = BRANCHES
|
||||
.captures_iter(&caps["branches"])
|
||||
.map(|captures| captures["branch"].to_owned())
|
||||
.collect::<Vec<_>>();
|
||||
if branches.is_empty() {
|
||||
// line without branches
|
||||
Line::from(vec![
|
||||
pre.into(),
|
||||
" ".into(),
|
||||
hash.into(),
|
||||
" ".into(),
|
||||
message.into(),
|
||||
])
|
||||
} else {
|
||||
// line withbranches
|
||||
let mut spans = vec![pre.into(), " ".into(), hash.into(), " ".into()];
|
||||
info!(?branches, "matched branch list");
|
||||
branches.sort();
|
||||
branches
|
||||
.into_iter()
|
||||
.map(|branch| Span::from(branch).style(Style::default().fg(Color::Blue)))
|
||||
.for_each(|span| {
|
||||
spans.push("[".into());
|
||||
spans.push(span);
|
||||
spans.push("]".into());
|
||||
});
|
||||
spans.push(" ".into());
|
||||
spans.push(message.into());
|
||||
Line::from(spans)
|
||||
}
|
||||
} else {
|
||||
// non-commit line
|
||||
Line::from(value.raw.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tracing::info;
|
||||
|
||||
use super::RE;
|
||||
|
||||
#[test_log::test]
|
||||
fn parse_log_line() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let line = "* 97b6853 (origin/next, origin/main, origin/dev, origin/HEAD) refactor(tui): simplify repo identity widget";
|
||||
RE.captures(line).map_or_else(
|
||||
|| Err("Failed to capture".into()),
|
||||
|caps| {
|
||||
info!(?caps, "");
|
||||
assert_eq!(&caps["pre"], "*");
|
||||
assert_eq!(&caps["hash"], "97b6853");
|
||||
assert_eq!(
|
||||
&caps["branches"],
|
||||
"origin/next, origin/main, origin/dev, origin/HEAD"
|
||||
);
|
||||
assert_eq!(
|
||||
&caps["message"],
|
||||
"refactor(tui): simplify repo identity widget"
|
||||
);
|
||||
Ok(())
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue