different style for hunk header

This commit is contained in:
Stephan Dilly 2020-03-16 22:00:38 +01:00
parent dd64532814
commit c5e7b1b8ae
3 changed files with 86 additions and 66 deletions

View file

@ -7,6 +7,7 @@ terminal ui (tui) frontend for git written in rust
* [x] show files on index
* [x] colorize diff
* [x] only show diff of selected file
* [ ] change detection
* [ ] allow selecting/diff index items
* [ ] allow scrolling diff
* [ ] support staging/unstaging

View file

@ -1,6 +1,9 @@
use crate::git_utils;
use crate::git_utils::Diff;
use crate::git_utils::DiffLine;
use crossterm::event::{Event, KeyCode};
use git2::{DiffFormat, DiffOptions, Repository, Status};
use git2::{Repository, Status};
use git_utils::DiffLineType;
use std::cmp;
use std::path::Path;
use tui::{
@ -11,29 +14,6 @@ use tui::{
Frame,
};
#[derive(Copy, Clone, PartialEq)]
pub enum DiffLineType {
None,
Header,
Add,
Delete,
}
impl Default for DiffLineType {
fn default() -> Self {
DiffLineType::None
}
}
#[derive(Default, PartialEq)]
pub struct DiffLine {
content: String,
line_type: DiffLineType,
}
#[derive(Default, PartialEq)]
pub struct Diff(Vec<DiffLine>);
#[derive(Default)]
pub struct App {
status_items: Vec<String>,
@ -94,7 +74,7 @@ impl App {
///
fn update_diff(&mut self) {
let new_diff = match self.status_select {
Some(i) => get_diff(Path::new(self.status_items[i].as_str())),
Some(i) => git_utils::get_diff(Path::new(self.status_items[i].as_str())),
None => Diff::default(),
};
@ -147,6 +127,13 @@ impl App {
content.into(),
Style::default().fg(Color::White).bg(Color::Green),
),
DiffLineType::Header => Text::Styled(
content.into(),
Style::default()
.fg(Color::Black)
.bg(Color::Gray)
.modifier(Modifier::BOLD),
),
_ => Text::Raw(content.into()),
}
})
@ -219,42 +206,3 @@ fn draw_list<B: Backend, T: AsRef<str>>(
.highlight_symbol(">")
.render(f, r);
}
///
fn get_diff(p: &Path) -> Diff {
let repo = Repository::init("./").unwrap();
if repo.is_bare() {
panic!("bare repo")
}
let mut opt = DiffOptions::new();
opt.pathspec(p);
let diff = repo
.diff_index_to_workdir(None, Some(&mut opt))
.unwrap();
let mut res = Vec::new();
diff.print(DiffFormat::Patch, |_delta, _hunk, line| {
let line_type = match line.origin() {
'H' => DiffLineType::Header,
'<' | '-' => DiffLineType::Delete,
'>' | '+' => DiffLineType::Add,
_ => DiffLineType::None,
};
let diff_line = DiffLine {
content: String::from_utf8_lossy(line.content()).to_string(),
line_type,
};
res.push(diff_line);
true
})
.unwrap();
Diff(res)
}

View file

@ -1,6 +1,77 @@
use git2::Status;
use git2::{DiffFormat, DiffOptions, Repository, Status};
use std::path::Path;
#[derive(Copy, Clone, PartialEq)]
pub enum DiffLineType {
None,
Header,
Add,
Delete,
}
impl Default for DiffLineType {
fn default() -> Self {
DiffLineType::None
}
}
#[derive(Default, PartialEq)]
pub struct DiffLine {
pub content: String,
pub line_type: DiffLineType,
}
#[derive(Default, PartialEq)]
pub struct Diff(pub Vec<DiffLine>);
///
pub fn on_index(s:&Status)->bool{
pub fn get_diff(p: &Path) -> Diff {
let repo = Repository::init("./").unwrap();
if repo.is_bare() {
panic!("bare repo")
}
let mut opt = DiffOptions::new();
opt.pathspec(p);
let diff = repo.diff_index_to_workdir(None, Some(&mut opt)).unwrap();
let mut res = Vec::new();
diff.print(DiffFormat::Patch, |_delta, _hunk, line| {
let origin = line.origin();
if origin != 'F' {
let line_type = match origin {
'H' => DiffLineType::Header,
'<' | '-' => DiffLineType::Delete,
'>' | '+' => DiffLineType::Add,
_ => DiffLineType::None,
};
let diff_line = DiffLine {
content: String::from_utf8_lossy(line.content()).to_string(),
line_type,
};
if line_type == DiffLineType::Header && res.len() > 0 {
res.push(DiffLine {
content: "\n".to_string(),
line_type: DiffLineType::None,
});
}
res.push(diff_line);
}
true
})
.unwrap();
Diff(res)
}
///
pub fn on_index(s: &Status) -> bool {
s.is_index_new() || s.is_index_modified()
}