Compare commits

..

4 commits

Author SHA1 Message Date
d0e252d16d feat(tui): highlight branchs in log
All checks were successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
2024-08-31 17:45:43 +01:00
1df982005e chore(tui): add regex dependency
All checks were successful
Rust / build (push) Successful in 10m6s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
Release Please / Release-plz (push) Successful in 1m16s
2024-08-31 14:17:28 +01:00
2abb36ad6c fix(tui): remove unused import
All checks were successful
Rust / build (push) Successful in 7m20s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
Release Please / Release-plz (push) Successful in 1m44s
2024-08-31 14:17:05 +01:00
576eaaf990 refactor(tui): introduce LogLine to wrap log formatting
All checks were successful
Rust / build (push) Successful in 10m0s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
Release Please / Release-plz (push) Successful in 1m58s
2024-08-31 13:33:45 +01:00
5 changed files with 103 additions and 6 deletions

1
Cargo.lock generated
View file

@ -1118,6 +1118,7 @@ dependencies = [
"pretty_assertions", "pretty_assertions",
"rand", "rand",
"ratatui", "ratatui",
"regex",
"rstest", "rstest",
"secrecy", "secrecy",
"sendmail", "sendmail",

View file

@ -32,6 +32,7 @@ directories = "5.0"
lazy_static = "1.5" lazy_static = "1.5"
color-eyre = "0.6" color-eyre = "0.6"
tui-scrollview = "0.4" tui-scrollview = "0.4"
regex = "1.10"
# CLI parsing # CLI parsing
clap = { version = "4.5", features = ["cargo", "derive"] } clap = { version = "4.5", features = ["cargo", "derive"] }

View file

@ -16,7 +16,7 @@ categories = { workspace = true }
default = ["forgejo", "github", "tui"] default = ["forgejo", "github", "tui"]
forgejo = ["git-next-forge-forgejo"] forgejo = ["git-next-forge-forgejo"]
github = ["git-next-forge-github"] github = ["git-next-forge-github"]
tui = ["ratatui", "directories", "lazy_static", "tui-scrollview"] tui = ["ratatui", "directories", "lazy_static", "tui-scrollview", "regex"]
[dependencies] [dependencies]
git-next-core = { workspace = true } git-next-core = { workspace = true }
@ -29,6 +29,7 @@ directories = { workspace = true, optional = true }
lazy_static = { workspace = true, optional = true } lazy_static = { workspace = true, optional = true }
color-eyre = { workspace = true } color-eyre = { workspace = true }
tui-scrollview = { workspace = true, optional = true } tui-scrollview = { workspace = true, optional = true }
regex = { workspace = true, optional = true }
# CLI parsing # CLI parsing
clap = { workspace = true } clap = { workspace = true }

View file

@ -1,9 +1,13 @@
use git_next_core::git::graph::Log;
// //
use git_next_core::git::graph::Log;
use lazy_static::lazy_static;
use ratatui::{ use ratatui::{
text::{Line, Text}, style::{Color, Style, Styled as _},
text::{Line, Span, Text},
widgets::{Paragraph, Widget}, widgets::{Paragraph, Widget},
}; };
use regex::Regex;
use tracing::info;
use super::HeightContraintLength; use super::HeightContraintLength;
@ -23,10 +27,102 @@ impl<'a> Widget for CommitLog<'a> {
Paragraph::new(Text::from( Paragraph::new(Text::from(
self.log self.log
.iter() .iter()
.map(ToString::to_string) .map(LogLine::new)
.map(Line::from) .map(Line::from)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
)) ))
.render(area, buf); .render(area, buf);
} }
} }
struct LogLine {
raw: String,
}
impl LogLine {
fn new(raw: impl Into<String>) -> Self {
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 {
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();
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()];
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["branch1"], "next");
assert_eq!(&caps["branch2"], "main");
assert_eq!(&caps["branch3"], "dev");
assert_eq!(&caps["branch4"], "HEAD");
assert_eq!(
&caps["message"],
"refactor(tui): simplify repo identity widget"
);
Ok(())
},
)
}
}

View file

@ -1,6 +1,4 @@
// //
use color_eyre::owo_colors::OwoColorize;
use git_next_core::{RepoAlias, RepoBranches}; use git_next_core::{RepoAlias, RepoBranches};
use ratatui::{ use ratatui::{
layout::Alignment, layout::Alignment,