summaryrefslogtreecommitdiffstats
path: root/src/show_commit/show_commit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/show_commit/show_commit.rs')
-rw-r--r--src/show_commit/show_commit.rs264
1 files changed, 51 insertions, 213 deletions
diff --git a/src/show_commit/show_commit.rs b/src/show_commit/show_commit.rs
index 561e967..810053e 100644
--- a/src/show_commit/show_commit.rs
+++ b/src/show_commit/show_commit.rs
@@ -1,5 +1,4 @@
use crate::commit::Commit;
-use crate::constants::MINIMUM_FULL_WINDOW_WIDTH;
use crate::display::DisplayColor;
use crate::git_interactive::GitInteractive;
use crate::input::{Input, InputHandler};
@@ -12,32 +11,46 @@ use crate::process::{
State,
};
use crate::scroll::ScrollPosition;
-use crate::show_commit::util::get_stat_item_segments;
-use crate::view::{LineSegment, View, ViewLine};
-use std::cmp;
-use unicode_segmentation::UnicodeSegmentation;
+use crate::show_commit::data::Data;
+use crate::view::View;
pub struct ShowCommit {
+ commit: Option<Result<Commit, String>>,
+ data: Data,
scroll_position: ScrollPosition,
}
impl ProcessModule for ShowCommit {
- fn activate(&mut self, _state: State, _git_interactive: &GitInteractive) {
+ fn activate(&mut self, _state: State, git_interactive: &GitInteractive) {
self.scroll_position.reset();
+ self.commit = Some(git_interactive.load_commit_stats());
}
- fn process(&mut self, git_interactive: &mut GitInteractive, _view: &View) -> ProcessResult {
+ fn deactivate(&mut self) {
+ self.data.reset();
+ }
+
+ fn process(&mut self, _git_interactive: &mut GitInteractive, view: &View) -> ProcessResult {
+ let (view_width, view_height) = view.get_view_size();
let mut result = ProcessResultBuilder::new();
- if let Err(e) = git_interactive.load_commit_stats() {
- result = result.error(e.as_str(), State::List(false));
+
+ if let Some(commit) = &self.commit {
+ match commit {
+ Ok(c) => self.data.update(&c, view_width, view_height),
+ Err(e) => {
+ result = result.error(e.as_str(), State::List(false));
+ self.data.reset()
+ },
+ }
}
+
result.build()
}
fn handle_input(
&mut self,
input_handler: &InputHandler,
- git_interactive: &mut GitInteractive,
+ _git_interactive: &mut GitInteractive,
view: &View,
) -> HandleInputResult
{
@@ -47,40 +60,24 @@ impl ProcessModule for ShowCommit {
let mut result = HandleInputResultBuilder::new(input);
match input {
Input::MoveCursorLeft => {
- self.scroll_position.scroll_left(
- view_width,
- self.get_max_line_length(
- git_interactive.get_commit_stats(),
- view_height >= MINIMUM_FULL_WINDOW_WIDTH,
- ),
- )
+ self.scroll_position
+ .scroll_left(view_width, self.get_max_line_length(view_height))
},
Input::MoveCursorRight => {
- self.scroll_position.scroll_right(
- view_width,
- self.get_max_line_length(
- git_interactive.get_commit_stats(),
- view_height >= MINIMUM_FULL_WINDOW_WIDTH,
- ),
- )
+ self.scroll_position
+ .scroll_right(view_width, self.get_max_line_length(view_height))
},
Input::MoveCursorDown => {
- self.scroll_position.scroll_down(
- view_height,
- self.get_commit_stats_length(git_interactive.get_commit_stats()),
- )
+ self.scroll_position
+ .scroll_down(view_height, self.get_commit_stats_length())
},
Input::MoveCursorUp => {
- self.scroll_position.scroll_up(
- view_height,
- self.get_commit_stats_length(git_interactive.get_commit_stats()),
- )
+ self.scroll_position
+ .scroll_up(view_height, self.get_commit_stats_length())
},
Input::Resize => {
- self.scroll_position.scroll_up(
- view_height as usize,
- self.get_commit_stats_length(git_interactive.get_commit_stats()),
- );
+ self.scroll_position
+ .scroll_up(view_height as usize, self.get_commit_stats_length());
},
_ => {
result = result.state(State::List(false));
@@ -89,105 +86,22 @@ impl ProcessModule for ShowCommit {
result.build()
}
- fn render(&self, view: &View, git_interactive: &GitInteractive) {
- let commit_data = git_interactive.get_commit_stats();
- let (window_width, window_height) = view.get_view_size();
+ fn render(&self, view: &View, _git_interactive: &GitInteractive) {
+ let (_, window_height) = view.get_view_size();
let view_height = window_height - 2;
- let is_full_width = window_width >= MINIMUM_FULL_WINDOW_WIDTH;
-
view.draw_title(false);
- let commit = match commit_data {
+ match &self.commit {
None => {
view.draw_error("Not commit data to show");
return;
},
- Some(c) => c,
- };
-
- let full_hash = commit.get_hash();
- let author = commit.get_author();
- let committer = commit.get_committer();
- let date = commit.get_date();
- let body = commit.get_body();
- let file_stats = commit.get_file_stats();
-
- let mut lines: Vec<ViewLine> = vec![];
-
- lines.push(ViewLine::new(vec![LineSegment::new_with_color(
- if is_full_width {
- format!("Commit: {}", full_hash)
- }
- else {
- let max_index = cmp::min(full_hash.len(), 8);
- format!("{:8} ", full_hash[0..max_index].to_string())
- }
- .as_str(),
- DisplayColor::IndicatorColor,
- )]));
-
- lines.push(ViewLine::new(vec![LineSegment::new(
- if is_full_width {
- format!("Date: {}", date.format("%c %z"))
- }
- else {
- format!("{}", date.format("%c %z"))
- }
- .as_str(),
- )]));
-
- if let Some(a) = author.to_string() {
- lines.push(ViewLine::new(vec![LineSegment::new(
- if is_full_width {
- format!("Author: {}", a)
- }
- else {
- format!("A: {}", a)
- }
- .as_str(),
- )]));
- }
-
- if let Some(c) = committer.to_string() {
- lines.push(ViewLine::new(vec![LineSegment::new(
- if is_full_width {
- format!("Committer: {}", c)
- }
- else {
- format!("C: {}", c)
- }
- .as_str(),
- )]))
+ Some(c) => c.as_ref().unwrap(), // safe unwrap
};
- match body {
- Some(b) => {
- for line in b.lines() {
- lines.push(ViewLine::new(vec![LineSegment::new(line)]));
- }
- },
- None => {},
- };
-
- lines.push(ViewLine::new(vec![LineSegment::new("")]));
-
- match file_stats {
- Some(stats) => {
- for stat in stats {
- lines.push(ViewLine::new(get_stat_item_segments(
- *stat.get_status(),
- stat.get_to_name().as_str(),
- stat.get_from_name().as_str(),
- is_full_width,
- )))
- }
- },
- None => {},
- }
-
view.draw_view_lines(
- lines,
+ self.data.get_lines(),
self.scroll_position.get_top_position(),
self.scroll_position.get_left_position(),
view_height,
@@ -201,13 +115,15 @@ impl ProcessModule for ShowCommit {
impl ShowCommit {
pub fn new() -> Self {
Self {
+ commit: None,
+ data: Data::new(),
scroll_position: ScrollPosition::new(3, 6, 3),
}
}
- fn get_commit_stats_length(&self, commit: &Option<Commit>) -> usize {
- match commit {
- Some(c) => {
+ fn get_commit_stats_length(&self) -> usize {
+ if let Some(commit) = &self.commit {
+ if let Ok(c) = commit {
let mut len = c.get_file_stats_length();
match c.get_body() {
@@ -216,94 +132,16 @@ impl ShowCommit {
},
None => {},
}
- len + 3 // author + date + commit hash
- },
- None => 0,
+ return len + 3; // author + date + commit hash
+ }
}
+ 0
}
- fn get_max_line_length(&self, commit: &Option<Commit>, is_full_width: bool) -> usize {
- match commit {
- Some(c) => {
- let full_hash = c.get_hash();
- let author = c.get_author();
- let committer = c.get_committer();
- let body = c.get_body();
- let file_stats = c.get_file_stats();
-
- let mut max_line_length = if is_full_width {
- full_hash.len() + 8 // 8 = "Commit: "
- }
- else {
- cmp::min(full_hash.len(), 8)
- };
-
- max_line_length = cmp::max(
- if is_full_width {
- 35 // "Date: Sun Jul 8 00:34:60 2001+09:30"
- }
- else {
- 29 // "Sun Jul 8 00:34:60 2001+09:30"
- },
- max_line_length,
- );
-
- if let Some(a) = author.to_string() {
- max_line_length = cmp::max(
- if is_full_width {
- UnicodeSegmentation::graphemes(a.as_str(), true).count() + 8 // 8 = "Author: "
- }
- else {
- UnicodeSegmentation::graphemes(a.as_str(), true).count() + 3 // 3 = "A: "
- },
- max_line_length,
- );
- }
-
- if let Some(c) = committer.to_string() {
- max_line_length = cmp::max(
- if is_full_width {
- UnicodeSegmentation::graphemes(c.as_str(), true).count() + 11 // 11 = "Committer: "
- }
- else {
- UnicodeSegmentation::graphemes(c.as_str(), true).count() + 3 // 3 = "C: "
- },
- max_line_length,
- );
- };
-
- if let Some(b) = body {
- for line in b.lines() {
- let line_length = UnicodeSegmentation::graphemes(line, true).count();
- if line_length > max_line_length {
- max_line_length = line_length;
- }
- }
- }
-
- if let Some(stats) = file_stats {
- let additional_line_length = if is_full_width {
- 13 // stat name + arrow
- }
- else {
- 3 // stat name + arrow
- };
-
- for stat in stats {
- let stat_line_length =
- UnicodeSegmentation::graphemes(stat.get_to_name().as_str(), true).count()
- + UnicodeSegmentation::graphemes(stat.get_from_name().as_str(), true).count()
- + additional_line_length;
-
- if stat_line_length > max_line_length {
- max_line_length = stat_line_length;
- }
- }
- }
-
- max_line_length
- },
- None => 0,
- }
+ fn get_max_line_length(&self, view_height: usize) -> usize {
+ self.data.get_max_line_length(
+ self.scroll_position.get_top_position(),
+ self.scroll_position.get_top_position() + view_height,
+ )
}
}