diff --git a/README.md b/README.md index aa9b19fd..fe13ba9e 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/app.rs b/src/app.rs index f729cdae..b8998046 100644 --- a/src/app.rs +++ b/src/app.rs @@ -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); - #[derive(Default)] pub struct App { status_items: Vec, @@ -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>( .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) -} diff --git a/src/git_utils.rs b/src/git_utils.rs index 775d3240..79b91475 100644 --- a/src/git_utils.rs +++ b/src/git_utils.rs @@ -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); /// -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() }