diff options
author | Tim Oram <dev@mitmaro.ca> | 2019-06-09 19:03:15 -0230 |
---|---|---|
committer | Tim Oram <dev@mitmaro.ca> | 2019-06-09 19:03:15 -0230 |
commit | 18a764b87a7573d2294bf5d0b700caa5622e4d4d (patch) | |
tree | 01578b21d6d396053b405df3e85bf38e11da3439 /src | |
parent | 2e08aad8a09f96eb11aabb3b226834d628b3d9b7 (diff) |
Move show commit into a module
Diffstat (limited to 'src')
-rw-r--r-- | src/application.rs | 59 | ||||
-rw-r--r-- | src/constants.rs | 5 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/show_commit/mod.rs | 5 | ||||
-rw-r--r-- | src/show_commit/show_commit.rs | 176 | ||||
-rw-r--r-- | src/show_commit/util.rs | 95 | ||||
-rw-r--r-- | src/view/view.rs | 272 | ||||
-rw-r--r-- | src/view/view_line.rs | 12 |
8 files changed, 330 insertions, 295 deletions
diff --git a/src/application.rs b/src/application.rs index c763e7e..e91435d 100644 --- a/src/application.rs +++ b/src/application.rs @@ -8,10 +8,12 @@ use crate::process::{ ExitStatus, HandleInputResult, HandleInputResultBuilder, + ProcessModule, ProcessResult, ProcessResultBuilder, State, }; +use crate::show_commit::ShowCommit; use crate::view::View; use crate::window::Window; use core::borrow::Borrow; @@ -25,6 +27,7 @@ pub struct Application<'a> { edit_content_cursor: usize, git_interactive: GitInteractive, input_handler: &'a InputHandler<'a>, + show_commit: ShowCommit, view: View<'a>, } @@ -42,6 +45,7 @@ impl<'a> Application<'a> { edit_content_cursor: 0, git_interactive, input_handler, + show_commit: ShowCommit::new(), view, } } @@ -63,7 +67,7 @@ impl<'a> Application<'a> { State::ExternalEditorFinish(_) => {}, State::Help(_) => {}, State::List => {}, - State::ShowCommit => {}, + State::ShowCommit => self.show_commit.activate(state, &self.git_interactive), State::VisualMode => {}, State::WindowSizeError(_) => {}, } @@ -82,7 +86,7 @@ impl<'a> Application<'a> { State::ExternalEditorFinish(_) => {}, State::Help(_) => {}, State::List => {}, - State::ShowCommit => {}, + State::ShowCommit => self.show_commit.deactivate(), State::VisualMode => {}, State::WindowSizeError(_) => {}, } @@ -101,7 +105,7 @@ impl<'a> Application<'a> { State::ExternalEditorFinish(_) => self.process_external_editor_finish(), State::Help(_) => ProcessResult::new(), State::List => self.process_list(), - State::ShowCommit => self.process_show_commit(), + State::ShowCommit => self.show_commit.process(&mut self.git_interactive), State::VisualMode => self.process_list(), State::WindowSizeError(_) => ProcessResult::new(), } @@ -161,14 +165,6 @@ impl<'a> Application<'a> { ProcessResult::new() } - pub fn process_show_commit(&mut self) -> ProcessResult { - let mut result = ProcessResultBuilder::new(); - if let Err(e) = self.git_interactive.load_commit_stats() { - result = result.error(e.as_str(), State::List); - } - result.build() - } - pub fn check_window_size(&self) -> bool { self.view.check_window_size() } @@ -188,7 +184,7 @@ impl<'a> Application<'a> { State::Help(help_state) => self.draw_help(help_state.borrow()), State::List => self.draw_main(false), State::VisualMode => self.draw_main(true), - State::ShowCommit => self.draw_show_commit(), + State::ShowCommit => self.show_commit.render(&self.view, &self.git_interactive), State::WindowSizeError(_) => self.draw_window_size_error(), } self.view.refresh() @@ -206,10 +202,6 @@ impl<'a> Application<'a> { self.view.draw_error(error_message); } - fn draw_show_commit(&self) { - self.view.draw_show_commit(self.git_interactive.get_commit_stats()); - } - fn draw_main(&self, visual_mode: bool) { self.view.draw_main( self.git_interactive.get_lines(), @@ -247,15 +239,15 @@ impl<'a> Application<'a> { self.view.draw_window_size_error(); } - fn get_input(&self) -> Input { + pub fn get_input(&self) -> Input { self.input_handler.get_input() } - fn get_confirm(&mut self) -> Input { + pub fn get_confirm(&mut self) -> Input { self.input_handler.get_confirm() } - fn get_character(&self) -> Input { + pub fn get_character(&self) -> Input { self.input_handler.get_character() } @@ -273,7 +265,10 @@ impl<'a> Application<'a> { State::Help(help_state) => self.handle_help_input(help_state.borrow()), State::List => self.handle_list_input(), State::VisualMode => self.handle_visual_mode_input(), - State::ShowCommit => self.handle_show_commit_input(), + State::ShowCommit => { + self.show_commit + .handle_input_with_view(&self.input_handler, &mut self.git_interactive, &self.view) + }, State::WindowSizeError(_) => self.handle_window_size_error_input(), } } @@ -340,29 +335,6 @@ impl<'a> Application<'a> { result.build() } - fn handle_show_commit_input(&mut self) -> HandleInputResult { - let input = self.get_input(); - let mut result = HandleInputResultBuilder::new(input); - match input { - Input::MoveCursorDown => { - self.view - .update_commit_top(false, false, self.git_interactive.get_commit_stats_length()); - }, - Input::MoveCursorUp => { - self.view - .update_commit_top(true, false, self.git_interactive.get_commit_stats_length()); - }, - Input::Resize => { - self.view - .update_commit_top(true, false, self.git_interactive.get_commit_stats_length()); - }, - _ => { - result = result.state(State::List); - }, - } - result.build() - } - fn handle_confirm_abort_input(&mut self) -> HandleInputResult { let input = self.get_confirm(); let mut result = HandleInputResultBuilder::new(input); @@ -496,7 +468,6 @@ impl<'a> Application<'a> { }, Input::ShowCommit => { if !self.git_interactive.get_selected_line_hash().is_empty() { - self.view.update_commit_top(false, true, 0); result = result.state(State::ShowCommit); } }, diff --git a/src/constants.rs b/src/constants.rs index 42dcba5..a51ef37 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -22,10 +22,7 @@ pub const SHORT_ERROR_MESSAGE_WIDTH: i32 = 16; pub const MINIMUM_WINDOW_HEIGHT: i32 = 5; // title + pad top + line + pad bottom + help pub const MINIMUM_COMPACT_WINDOW_WIDTH: i32 = 20; //">s ccc mmmmmmmmmmmmm".len() -pub const MINIMUM_FULL_WINDOW_WIDTH: i32 = 34; // " > squash cccccccc mmmmmmmmmmmmm %".len() - -pub const TO_FILE_INDICATOR: &str = " -> "; -pub const TO_FILE_INDICATOR_SHORT: &str = ">"; +pub const MINIMUM_FULL_WINDOW_WIDTH: usize = 34; // " > squash cccccccc mmmmmmmmmmmmm %".len() pub const NAME: &str = "interactive-rebase-tool"; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/src/main.rs b/src/main.rs index f12bf25..79854f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ mod input; mod line; mod process; mod scroll; +mod show_commit; mod view; mod window; diff --git a/src/show_commit/mod.rs b/src/show_commit/mod.rs new file mode 100644 index 0000000..9294506 --- /dev/null +++ b/src/show_commit/mod.rs @@ -0,0 +1,5 @@ +#[allow(clippy::module_inception)] +mod show_commit; +mod util; + +pub use self::show_commit::ShowCommit; diff --git a/src/show_commit/show_commit.rs b/src/show_commit/show_commit.rs new file mode 100644 index 0000000..5ff8340 --- /dev/null +++ b/src/show_commit/show_commit.rs @@ -0,0 +1,176 @@ +use crate::constants::MINIMUM_FULL_WINDOW_WIDTH; +use crate::git_interactive::GitInteractive; +use crate::input::{Input, InputHandler}; +use crate::process::{ + HandleInputResult, + HandleInputResultBuilder, + ProcessModule, + ProcessResult, + ProcessResultBuilder, + State, +}; +use crate::scroll::ScrollPosition; +use crate::show_commit::util::get_stat_item_segments; +use crate::view::{LineSegment, View, ViewLine}; +use crate::window::WindowColor; +use std::cmp; + +pub struct ShowCommit { + scroll_position: ScrollPosition, +} + +impl ProcessModule for ShowCommit { + fn activate(&mut self, _state: State, _git_interactive: &GitInteractive) { + self.scroll_position.reset(); + } + + fn process(&mut self, git_interactive: &mut GitInteractive) -> ProcessResult { + let mut result = ProcessResultBuilder::new(); + if let Err(e) = git_interactive.load_commit_stats() { + result = result.error(e.as_str(), State::List); + } + 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(); + 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 { + 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(), + WindowColor::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(), + )])) + }; + + 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.scroll_position.get_position(), view_height); + + view.set_color(WindowColor::IndicatorColor); + view.draw_str("Any key to close"); + } +} + +impl ShowCommit { + pub fn new() -> Self { + Self { + scroll_position: ScrollPosition::new(3, 6, 3), + } + } + + pub fn handle_input_with_view( + &mut self, + input_handler: &InputHandler, + git_interactive: &mut GitInteractive, + view: &View, + ) -> HandleInputResult + { + let (_, window_height) = view.get_view_size(); + + let input = input_handler.get_input(); + let mut result = HandleInputResultBuilder::new(input); + match input { + Input::MoveCursorDown => { + self.scroll_position + .scroll_down(window_height, git_interactive.get_commit_stats_length()) + }, + Input::MoveCursorUp => { + self.scroll_position + .scroll_up(window_height, git_interactive.get_commit_stats_length()) + }, + Input::Resize => { + self.scroll_position + .scroll_up(window_height as usize, git_interactive.get_commit_stats_length()); + }, + _ => { + result = result.state(State::List); + }, + } + result.build() + } +} diff --git a/src/show_commit/util.rs b/src/show_commit/util.rs new file mode 100644 index 0000000..9d36496 --- /dev/null +++ b/src/show_commit/util.rs @@ -0,0 +1,95 @@ +use crate::view::LineSegment; +use crate::window::WindowColor; +use git2::Delta; + +fn get_file_stat_color(status: Delta) -> WindowColor { + match status { + Delta::Added => WindowColor::DiffAddColor, + Delta::Copied => WindowColor::DiffAddColor, + Delta::Deleted => WindowColor::DiffRemoveColor, + Delta::Modified => WindowColor::DiffChangeColor, + Delta::Renamed => WindowColor::DiffChangeColor, + Delta::Typechange => WindowColor::DiffChangeColor, + + // these should never happen in a rebase + Delta::Conflicted => WindowColor::Foreground, + Delta::Ignored => WindowColor::Foreground, + Delta::Unmodified => WindowColor::Foreground, + Delta::Unreadable => WindowColor::Foreground, + Delta::Untracked => WindowColor::Foreground, + } +} + +fn get_file_stat_abbreviated(status: Delta) -> String { + match status { + Delta::Added => String::from("A "), + Delta::Copied => String::from("C "), + Delta::Deleted => String::from("D "), + Delta::Modified => String::from("M "), + Delta::Renamed => String::from("R "), + Delta::Typechange => String::from("T "), + + // these should never happen in a rebase + Delta::Conflicted => String::from("X "), + Delta::Ignored => String::from("X "), + Delta::Unmodified => String::from("X "), + Delta::Unreadable => String::from("X "), + Delta::Untracked => String::from("X "), + } +} + +fn get_file_stat_long(status: Delta) -> String { + match status { + Delta::Added => format!("{:>8}: ", "added"), + Delta::Copied => format!("{:>8}: ", "copied"), + Delta::Deleted => format!("{:>8}: ", "deleted"), + Delta::Modified => format!("{:>8}: ", "modified"), + Delta::Renamed => format!("{:>8}: ", "renamed"), + Delta::Typechange => format!("{:>8}: ", "changed"), + + // these should never happen in a rebase + Delta::Conflicted => format!("{:>8}: ", "unknown"), + Delta::Ignored => format!("{:>8}: ", "unknown"), + Delta::Unmodified => format!("{:>8}: ", "unknown"), + Delta::Unreadable => format!("{:>8}: ", "unknown"), + Delta::Untracked => format!("{:>8}: ", "unknown"), + } +} + +pub fn get_stat_item_segments(status: Delta, to_name: &str, from_name: &str, is_full_width: bool) -> Vec<LineSegment> { + let status_name = if is_full_width { + get_file_stat_long(status) + } + else { + get_file_stat_abbreviated(status) + }; + + let color = get_file_stat_color(status); + + let to_file_indicator = if is_full_width { " -> " } else { ">" }; + + match status { + Delta::Copied => { + vec![ + LineSegment::new_with_color(status_name.clone().as_str(), color), + LineSegment::new_with_color(to_name, WindowColor::Foreground), + LineSegment::new(to_file_indicator), + LineSegment::new_with_color(from_name, WindowColor::DiffAddColor), + ] + }, + Delta::Renamed => { + vec![ + LineSegment::new_with_color(status_name.as_str(), color), + LineSegment::new_with_color(to_name, WindowColor::DiffRemoveColor), + LineSegment::new(to_file_indicator), + LineSegment::new_with_color(from_name, WindowColor::DiffAddColor), + ] + }, + _ => { + vec![ + LineSegment::new_with_color(status_name.as_str(), color), + LineSegment::new_with_color(from_name, color), + ] + }, + } +} diff --git a/src/view/view.rs b/src/view/view.rs index 92f074c..0ab26f9 100644 --- a/src/view/view.rs +++ b/src/view/view.rs @@ -1,5 +1,4 @@ use crate::action::Action; -use crate::commit::Commit; use crate::constants::{ HEIGHT_ERROR_MESSAGE, LIST_FOOTER_COMPACT, @@ -18,8 +17,6 @@ use crate::constants::{ TITLE_LENGTH, TITLE_SHORT, TITLE_SHORT_LENGTH, - TO_FILE_INDICATOR, - TO_FILE_INDICATOR_SHORT, VISUAL_MODE_FOOTER_COMPACT, VISUAL_MODE_FOOTER_COMPACT_WIDTH, VISUAL_MODE_FOOTER_FULL, @@ -30,12 +27,10 @@ use crate::scroll::{get_scroll_position, ScrollPosition}; use crate::view::{LineSegment, ViewLine}; use crate::window::Window; use crate::window::WindowColor; -use git2::Delta; use std::cmp; use unicode_segmentation::UnicodeSegmentation; pub struct View<'v> { - commit_top: ScrollPosition, help_top: ScrollPosition, main_top: ScrollPosition, window: &'v Window<'v>, @@ -44,13 +39,20 @@ pub struct View<'v> { impl<'v> View<'v> { pub fn new(window: &'v Window) -> Self { Self { - commit_top: ScrollPosition::new(3, 6, 3), help_top: ScrollPosition::new(3, 6, 3), main_top: ScrollPosition::new(2, 1, 1), window, } } + pub fn draw_str(&self, s: &str) { + self.window.draw_str(s); + } + + pub fn set_color(&self, color: WindowColor) { + self.window.color(color); + } + pub fn check_window_size(&self) -> bool { let (window_width, window_height) = self.window.get_window_size(); !(window_width <= MINIMUM_COMPACT_WINDOW_WIDTH || window_height <= MINIMUM_WINDOW_HEIGHT) @@ -70,6 +72,11 @@ impl<'v> View<'v> { self.window.clear(); } + pub fn get_view_size(&self) -> (usize, usize) { + let (view_width, view_height) = self.window.get_window_size(); + (view_width as usize, view_height as usize) + } + pub fn refresh(&self) { self.window.refresh(); } @@ -130,7 +137,7 @@ impl<'v> View<'v> { let window_width = if scrollbar { window_width - 1 } else { window_width } as usize; let mut start = 0; - for segment in &line.segments { + for segment in line.get_segments() { start += segment.draw(window_width - start, &self.window); if start >= window_width { break; @@ -143,7 +150,7 @@ impl<'v> View<'v> { } } - fn draw_title(&self, show_help: bool) { + pub fn draw_title(&self, show_help: bool) { self.window.color(WindowColor::Foreground); self.window.set_style(false, true, true); let (window_width, _) = self.window.get_window_size(); @@ -239,9 +246,11 @@ impl<'v> View<'v> { }, None => false, }; - view_lines.push(ViewLine { - segments: self.get_todo_line_segments(line, selected_index == index, is_cursor_line), - }); + view_lines.push(ViewLine::new(self.get_todo_line_segments( + line, + selected_index == index, + is_cursor_line, + ))); } self.window.clear(); @@ -273,13 +282,14 @@ impl<'v> View<'v> { pub fn get_todo_line_segments(&self, line: &Line, is_cursor_line: bool, selected: bool) -> Vec<LineSegment> { let (window_width, _) = self.window.get_window_size(); + let view_width = window_width as usize; let mut segments: Vec<LineSegment> = vec![]; let action = line.get_action(); self.window.set_style(false, false, false); - if window_width >= MINIMUM_FULL_WINDOW_WIDTH { + if view_width >= MINIMUM_FULL_WINDOW_WIDTH { segments.push(LineSegment::new_with_color_and_style( if is_cursor_line || selected { " > " } else { " " }, WindowColor::Foreground, @@ -341,19 +351,6 @@ impl<'v> View<'v> { segments } - pub fn update_commit_top(&mut self, scroll_up: bool, reset: bool, lines_length: usize) { - let (_, window_height) = self.window.get_window_size(); - if reset { - self.commit_top.reset(); - } - else if scroll_up { - self.commit_top.scroll_up(window_height as usize, lines_length); - } - else { - self.commit_top.scroll_down(window_height as usize, lines_length); - } - } - pub fn update_help_top(&self, scroll_up: bool, reset: bool, help_lines: &[(&str, &str)]) { let (_, window_height) = self.window.get_window_size(); if reset { @@ -374,12 +371,10 @@ impl<'v> View<'v> { let mut view_lines: Vec<ViewLine> = vec![]; for line in help_lines { - view_lines.push(ViewLine { - segments: vec![ - LineSegment::new_with_color(format!(" {:4} ", line.0).as_str(), WindowColor::IndicatorColor), - LineSegment::new(line.1), - ], - }) + view_lines.push(ViewLine::new(vec![ + LineSegment::new_with_color(format!(" {:4} ", line.0).as_str(), WindowColor::IndicatorColor), + LineSegment::new(line.1), + ])); } self.window.set_style(false, false, false); @@ -414,221 +409,6 @@ impl<'v> View<'v> { self.window.draw_str("Exiting...") } - fn get_file_stat_long(&self, status: Delta) -> String { - match status { - Delta::Added => format!("{:>8}: ", "added"), - Delta::Copied => format!("{:>8}: ", "copied"), - Delta::Deleted => format!("{:>8}: ", "deleted"), - Delta::Modified => format!("{:>8}: ", "modified"), - Delta::Renamed => format!("{:>8}: ", "renamed"), - Delta::Typechange => format!("{:>8}: ", "changed"), - - // these should never happen in a rebase - Delta::Conflicted => format!("{:>8}: ", "unknown"), - Delta::Ignored => format!("{:>8}: ", "unknown"), - Delta::Unmodified => format!("{:>8}: ", "unknown"), - Delta::Unreadable => format!("{:>8}: ", "unknown"), - Delta::Untracked => format!("{:>8}: ", "unknown"), - } - } - - fn get_file_stat_abbreviated(&self, status: Delta) -> String { - match status { - Delta::Added => String::from("A "), - Delta::Copied => String::from("C "), - Delta::Deleted => String::from("D "), - Delta::Modified => String::from("M "), - Delta::Renamed => String::from("R "), - Delta::Typechange => String::from("T "), - - // these should never happen in a rebase - Delta::Conflicted => String::from("X "), - Delta::Ignored => String::from("X "), - Delta::Unmodified => String::from("X "), - Delta::Unreadable => String::from("X "), - Delta::Untracked => String::from("X "), - } - } - - fn get_file_stat_color(&self, status: Delta) -> WindowColor { - match status { - Delta::Added => WindowColor::DiffAddColor, - Delta::Copied => WindowColor::DiffAddColor, - Delta::Deleted => WindowColor::DiffRemoveColor, - Delta::Modified => WindowColor::DiffChangeColor, - Delta::Renamed => WindowColor::DiffChangeColor, - Delta::Typechange => WindowColor::DiffChangeColor, - - // these should never happen in a rebase - Delta::Conflicted => WindowColor::Foreground, - Delta::Ignored => WindowColor::Foreground, - Delta::Unmodified => WindowColor::Foreground, - Delta::Unreadable => WindowColor::Foreground, - Delta::Untracked => WindowColor::Foreground, - } - } - - fn get_stat_item_segments(&self, status: Delta, to_name: &str, from_name: &str) -> Vec<LineSegment> { - let (window_width, _) = self.window.get_window_size(); - - let status_name = if window_width >= MINIMUM_FULL_WINDOW_WIDTH { - self.get_file_stat_long(status) - } - else { - self.get_file_stat_abbreviated(status) - }; - - let color = self.get_file_stat_color(status); - - let to_file_indicator = if window_width >= MINIMUM_FULL_WINDOW_WIDTH { - TO_FILE_INDICATOR - } - else { - TO_FILE_INDICATOR_SHORT - }; - - match status { - Delta::Copied => { - vec![ - LineSegment::new_with_color(status_name.clone().as_str(), color), - LineSegment::new_with_color(to_name, WindowColor::Foreground), - LineSegment::new(to_file_indicator), - LineSegment::new_with_color(from_name, WindowColor::DiffAddColor), - ] - }, - Delta::Renamed => { - vec![ - LineSegment::new_with_color(status_name.as_str(), color), - LineSegment::new_with_color(to_name, WindowColor::DiffRemoveColor), - LineSegment::new(to_file_indicator), - LineSegment::new_with_color(from_name, WindowColor::DiffAddColor), - ] - }, - _ => { - vec![ - LineSegment::new_with_color(status_name.as_str(), color), - LineSegment::new_with_color(from_name, color), - ] - }, - } - } - - pub fn draw_show_commit(&self, commit_data: &Option<Commit>) { - let (window_width, window_height) = self.window.get_window_size(); - let view_height = window_height as usize - 2; - - let is_full_width = window_width >= MINIMUM_FULL_WINDOW_WIDTH; - - self.window.clear(); - self.draw_title(false); - - let commit = match commit_data { - None => { - self.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 { - segments: 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(), - WindowColor::IndicatorColor, - )], - }); - - lines.push(ViewLine { - segments: 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 { - segments: 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 { - segments: vec![LineSegment::new( - if is_full_width { - format!("Committer: {}", c) - } - else { - format!("C: {}", c) - } - .as_str(), - )], - }) - }; - - match body { - Some(b) => { - for line in b.lines() { - lines.push(ViewLine { - segments: vec![LineSegment::new(line)], - }); - } - }, - None => {}, - }; - - lines.push(ViewLine { - segments: vec![LineSegment::new("")], - }); - - match file_stats { - Some(stats) => { - for stat in stats { - lines.push(ViewLine { - segments: self.get_stat_item_segments( - *stat.get_status(), - stat.get_to_name().as_str(), - stat.get_from_name().as_str(), - ), - }) - } - }, - None => {}, - } - - self.draw_view_lines(lines, self.commit_top.get_position(), view_height); - - self.window.color(WindowColor::IndicatorColor); - self.window.draw_str("Any key to close"); - } - pub fn draw_edit(&self, line: &str, pointer: usize) { self.draw_title(false); self.window.set_style(false, true, false); diff --git a/src/view/view_line.rs b/src/view/view_line.rs index c8f921c..818b025 100644 --- a/src/view/view_line.rs +++ b/src/view/view_line.rs @@ -1,5 +1,15 @@ use crate::view::LineSegment; pub struct ViewLine { - pub segments: Vec<LineSegment>, + segments: Vec<LineSegment>, +} + +impl ViewLine { + pub fn new(segments: Vec<LineSegment>) -> Self { + Self { segments } + } + + pub fn get_segments(&self) -> &Vec<LineSegment> { + &self.segments + } } |