diff options
author | Tim Oram <dev@mitmaro.ca> | 2019-06-30 23:08:12 -0230 |
---|---|---|
committer | Tim Oram <dev@mitmaro.ca> | 2019-06-30 23:08:12 -0230 |
commit | 017735fa8561e4a25b54af9f2a60c52ee8e0d347 (patch) | |
tree | 112daf87d0d8353fea4a58cad3faf4de67de826b | |
parent | dfe6500b89c248d53c227bf354751b0b75234210 (diff) |
Move list to module
-rw-r--r-- | src/application.rs | 182 | ||||
-rw-r--r-- | src/confirm_abort/confirm_abort.rs | 2 | ||||
-rw-r--r-- | src/confirm_rebase/confirm_rebase.rs | 2 | ||||
-rw-r--r-- | src/constants.rs | 8 | ||||
-rw-r--r-- | src/edit/edit.rs | 2 | ||||
-rw-r--r-- | src/error/error.rs | 2 | ||||
-rw-r--r-- | src/external_editor/external_editor.rs | 4 | ||||
-rw-r--r-- | src/git_interactive.rs | 2 | ||||
-rw-r--r-- | src/list/list.rs | 306 | ||||
-rw-r--r-- | src/list/mod.rs | 6 | ||||
-rw-r--r-- | src/list/utils.rs | 15 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/process/process.rs | 2 | ||||
-rw-r--r-- | src/process/state.rs | 3 | ||||
-rw-r--r-- | src/show_commit/show_commit.rs | 4 | ||||
-rw-r--r-- | src/view/view.rs | 172 |
16 files changed, 373 insertions, 340 deletions
diff --git a/src/application.rs b/src/application.rs index 20c64a6..d324d01 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,4 +1,3 @@ -use crate::action::Action; use crate::config::Config; use crate::confirm_abort::ConfirmAbort; use crate::confirm_rebase::ConfirmRebase; @@ -9,13 +8,27 @@ use crate::exiting::Exiting; use crate::external_editor::ExternalEditor; use crate::git_interactive::GitInteractive; use crate::input::{Input, InputHandler}; -use crate::process::{ExitStatus, HandleInputResult, HandleInputResultBuilder, ProcessModule, ProcessResult, State}; +use crate::list::List; +use crate::process::{HandleInputResult, HandleInputResultBuilder, ProcessModule, ProcessResult, State}; use crate::show_commit::ShowCommit; use crate::view::View; use core::borrow::Borrow; +fn get_help_lines(help_state: &State) -> &[(&str, &str)] { + if let State::List(visual_mode) = *help_state { + if visual_mode { + LIST_HELP_LINES + } + else { + VISUAL_MODE_HELP_LINES + } + } + else { + &[] + } +} + pub struct Application<'a> { - config: &'a Config, confirm_abort: ConfirmAbort, confirm_rebase: ConfirmRebase, edit: Edit, @@ -24,6 +37,7 @@ pub struct Application<'a> { external_editor: ExternalEditor<'a>, git_interactive: GitInteractive, input_handler: &'a InputHandler<'a>, + list: List<'a>, show_commit: ShowCommit, view: View<'a>, } @@ -37,7 +51,6 @@ impl<'a> Application<'a> { ) -> Self { Self { - config, confirm_abort: ConfirmAbort::new(), confirm_rebase: ConfirmRebase::new(), edit: Edit::new(), @@ -46,15 +59,12 @@ impl<'a> Application<'a> { external_editor: ExternalEditor::new(config), git_interactive, input_handler, + list: List::new(config), show_commit: ShowCommit::new(), view, } } - fn get_cursor_index(&self) -> usize { - *self.git_interactive.get_selected_line_index() - 1 - } - pub fn activate(&mut self, state: State) { match state { State::ConfirmAbort => self.confirm_abort.activate(state, &self.git_interactive), @@ -64,9 +74,8 @@ impl<'a> Application<'a> { State::Exiting => self.exiting.activate(state, &self.git_interactive), State::ExternalEditor => self.external_editor.activate(state, &self.git_interactive), State::Help(_) => {}, - State::List => {}, + State::List(_) => self.list.activate(state, &self.git_interactive), State::ShowCommit => self.show_commit.activate(state, &self.git_interactive), - State::VisualMode => {}, State::WindowSizeError(_) => {}, } } @@ -80,9 +89,8 @@ impl<'a> Application<'a> { State::Exiting => self.exiting.deactivate(), State::ExternalEditor => self.external_editor.deactivate(), State::Help(_) => {}, - State::List => {}, + State::List(_) => self.list.deactivate(), State::ShowCommit => self.show_commit.deactivate(), - State::VisualMode => {}, State::WindowSizeError(_) => {}, } } @@ -96,20 +104,12 @@ impl<'a> Application<'a> { State::Exiting => self.exiting.process(&mut self.git_interactive), State::ExternalEditor => self.external_editor.process(&mut self.git_interactive), State::Help(_) => ProcessResult::new(), - State::List => self.process_list(), + State::List(_) => self.list.process_with_view(&mut self.git_interactive, &self.view), State::ShowCommit => self.show_commit.process(&mut self.git_interactive), - State::VisualMode => self.process_list(), State::WindowSizeError(_) => ProcessResult::new(), } } - pub fn process_list(&mut self) -> ProcessResult { - let lines = self.git_interactive.get_lines(); - let selected_index = self.get_cursor_index(); - self.view.update_main_top(lines.len(), selected_index); - ProcessResult::new() - } - pub fn check_window_size(&self) -> bool { self.view.check_window_size() } @@ -124,36 +124,15 @@ impl<'a> Application<'a> { State::Exiting => self.exiting.render(&self.view, &self.git_interactive), State::ExternalEditor => self.external_editor.render(&self.view, &self.git_interactive), State::Help(help_state) => self.draw_help(help_state.borrow()), - State::List => self.draw_main(false), - State::VisualMode => self.draw_main(true), + State::List(_) => self.list.render(&self.view, &self.git_interactive), State::ShowCommit => self.show_commit.render(&self.view, &self.git_interactive), State::WindowSizeError(_) => self.draw_window_size_error(), } self.view.refresh() } - fn draw_main(&self, visual_mode: bool) { - self.view.draw_main( - self.git_interactive.get_lines(), - self.get_cursor_index(), - if visual_mode { - Some(self.git_interactive.get_visual_start_index() - 1) - } - else { - None - }, - ); - } - fn draw_help(&self, help_state: &State) { - self.view.draw_help( - if *help_state == State::List { - LIST_HELP_LINES - } - else { - VISUAL_MODE_HELP_LINES - }, - ); + self.view.draw_help(get_help_lines(help_state)) } fn draw_window_size_error(&self) { @@ -185,8 +164,10 @@ impl<'a> Application<'a> { .handle_input(&self.input_handler, &mut self.git_interactive) }, 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::List(_) => { + self.list + .handle_input_with_view(&self.input_handler, &mut self.git_interactive, &self.view) + }, State::ShowCommit => { self.show_commit .handle_input_with_view(&self.input_handler, &mut self.git_interactive, &self.view) @@ -196,23 +177,17 @@ impl<'a> Application<'a> { } fn handle_help_input(&mut self, help_state: &State) -> HandleInputResult { - let help_lines = if *help_state == State::List { - LIST_HELP_LINES - } - else { - VISUAL_MODE_HELP_LINES - }; let input = self.get_input(); let mut result = HandleInputResultBuilder::new(input); match input { Input::MoveCursorDown => { - self.view.update_help_top(false, false, help_lines); + self.view.update_help_top(false, false, get_help_lines(help_state)); }, Input::MoveCursorUp => { - self.view.update_help_top(true, false, help_lines); + self.view.update_help_top(true, false, get_help_lines(help_state)); }, Input::Resize => { - self.view.update_help_top(true, true, help_lines); + self.view.update_help_top(true, true, get_help_lines(help_state)); }, _ => { result = result.state(help_state.clone()); @@ -221,96 +196,6 @@ impl<'a> Application<'a> { result.build() } - fn handle_visual_mode_input(&mut self) -> HandleInputResult { - let input = self.get_input(); - let mut result = HandleInputResultBuilder::new(input); - match input { - Input::MoveCursorDown => { - self.git_interactive.move_cursor_down(1); - }, - Input::MoveCursorUp => { - self.git_interactive.move_cursor_up(1); - }, - Input::MoveCursorPageDown => { - self.git_interactive.move_cursor_down(5); - }, - Input::MoveCursorPageUp => { - self.git_interactive.move_cursor_up(5); - }, - Input::ActionDrop => self.git_interactive.set_visual_range_action(Action::Drop), - Input::ActionEdit => self.git_interactive.set_visual_range_action(Action::Edit), - Input::ActionFixup => self.git_interactive.set_visual_range_action(Action::Fixup), - Input::ActionPick => self.git_interactive.set_visual_range_action(Action::Pick), - Input::ActionReword => self.git_interactive.set_visual_range_action(Action::Reword), - Input::ActionSquash => self.git_interactive.set_visual_range_action(Action::Squash), - Input::SwapSelectedDown => self.git_interactive.swap_visual_range_down(), - Input::SwapSelectedUp => self.git_interactive.swap_visual_range_up(), - Input::ToggleVisualMode => { - result = result.state(State::List); - }, - Input::Help => { - self.view.update_help_top(false, true, VISUAL_MODE_HELP_LINES); - result = result.help(State::VisualMode); - }, - _ => {}, - } - result.build() - } - - pub fn handle_list_input(&mut self) -> HandleInputResult { - let input = self.get_input(); - let mut result = HandleInputResultBuilder::new(input); - match input { - Input::Help => { - self.view.update_help_top(false, true, LIST_HELP_LINES); - result = result.help(State::List); - }, - Input::ShowCommit => { - if !self.git_interactive.get_selected_line_hash().is_empty() { - result = result.state(State::ShowCommit); - } - }, - Input::Abort => { - result = result.state(State::ConfirmAbort); - }, - Input::ForceAbort => { - self.git_interactive.clear(); - result = result.exit_status(ExitStatus::Good).state(State::Exiting); - }, - Input::Rebase => { - result = result.state(State::ConfirmRebase); - }, - Input::ForceRebase => { - result = result.exit_status(ExitStatus::Good).state(State::Exiting); - }, - Input::ActionBreak => self.git_interactive.toggle_break(), - Input::ActionDrop => self.set_selected_line_action(Action::Drop), - Input::ActionEdit => self.set_selected_line_action(Action::Edit), - Input::ActionFixup => self.set_selected_line_action(Action::Fixup), - Input::ActionPick => self.set_selected_line_action(Action::Pick), - Input::ActionReword => self.set_selected_line_action(Action::Reword), - Input::ActionSquash => self.set_selected_line_action(Action::Squash), - Input::Edit => { - if *self.git_interactive.get_selected_line_action() == Action::Exec { - result = result.state(State::Edit); - } - }, - Input::SwapSelectedDown => self.git_interactive.swap_selected_down(), - Input::SwapSelectedUp => self.git_interactive.swap_selected_up(), - Input::MoveCursorDown => self.git_interactive.move_cursor_down(1), - Input::MoveCursorUp => self.git_interactive.move_cursor_up(1), - Input::MoveCursorPageDown => self.git_interactive.move_cursor_down(5), - Input::MoveCursorPageUp => self.git_interactive.move_cursor_up(5), - Input::ToggleVisualMode => { - self.git_interactive.start_visual_mode(); - result = result.state(State::VisualMode); - }, - Input::OpenInEditor => result = result.state(State::ExternalEditor), - _ => {}, - } - result.build() - } - pub fn handle_window_size_error_input(&mut self) -> HandleInputResult { HandleInputResult::new(self.get_input()) } @@ -318,11 +203,4 @@ impl<'a> Application<'a> { pub fn write_file(&self) -> Result<(), String> { self.git_interactive.write_file() } - - fn set_selected_line_action(&mut self, action: Action) { - self.git_interactive.set_selected_line_action(action); - if self.config.auto_select_next { - self.git_interactive.move_cursor_down(1); - } - } } diff --git a/src/confirm_abort/confirm_abort.rs b/src/confirm_abort/confirm_abort.rs index 0caa8c9..9fe3464 100644 --- a/src/confirm_abort/confirm_abort.rs +++ b/src/confirm_abort/confirm_abort.rs @@ -20,7 +20,7 @@ impl ProcessModule for ConfirmAbort { result = result.exit_status(ExitStatus::Good).state(State::Exiting); }, Input::No => { - result = result.state(State::List); + result = result.state(State::List(false)); }, _ => {}, } diff --git a/src/confirm_rebase/confirm_rebase.rs b/src/confirm_rebase/confirm_rebase.rs index 1189ff2..f341429 100644 --- a/src/confirm_rebase/confirm_rebase.rs +++ b/src/confirm_rebase/confirm_rebase.rs @@ -19,7 +19,7 @@ impl ProcessModule for ConfirmRebase { result = result.exit_status(ExitStatus::Good).state(State::Exiting); }, Input::No => { - result = result.state(State::List); + result = result.state(State::List(false)); }, _ => {}, } diff --git a/src/constants.rs b/src/constants.rs index a51ef37..2a6ffd8 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -6,14 +6,14 @@ pub const TITLE_HELP_INDICATOR: &str = "Help: ?"; pub const TITLE_HELP_INDICATOR_LENGTH: i32 = 7; pub const LIST_FOOTER_FULL: &str = " up, down, q/Q, w/W, c, j, k, b, p, r, e, s, f, d, E, !, ?"; -pub const LIST_FOOTER_FULL_WIDTH: i32 = 58; +pub const LIST_FOOTER_FULL_WIDTH: usize = 58; pub const LIST_FOOTER_COMPACT: &str = "up,dn.q/Q,w/W,c,j,k,b,p,r,e,s,f,d,E,!,?"; -pub const LIST_FOOTER_COMPACT_WIDTH: i32 = 39; +pub const LIST_FOOTER_COMPACT_WIDTH: usize = 39; pub const VISUAL_MODE_FOOTER_FULL: &str = "(VISUAL) up, down, j, k, p, r, e, s, f, d, ?"; -pub const VISUAL_MODE_FOOTER_FULL_WIDTH: i32 = 44; +pub const VISUAL_MODE_FOOTER_FULL_WIDTH: usize = 44; pub const VISUAL_MODE_FOOTER_COMPACT: &str = "(V) up,down,j,k,p,r,e,s,f,d,?"; -pub const VISUAL_MODE_FOOTER_COMPACT_WIDTH: i32 = 29; +pub const VISUAL_MODE_FOOTER_COMPACT_WIDTH: usize = 29; pub const HEIGHT_ERROR_MESSAGE: &str = "Window too small, increase height to continue\n"; pub const MINIMUM_WINDOW_HEIGHT_ERROR_WIDTH: i32 = 45; diff --git a/src/edit/edit.rs b/src/edit/edit.rs index e7a6fa9..d1dfd6f 100644 --- a/src/edit/edit.rs +++ b/src/edit/edit.rs @@ -35,7 +35,7 @@ impl ProcessModule for Edit { EditState::Active => {}, EditState::Finish => { git_interactive.edit_selected_line(self.content.as_str()); - result = result.state(State::List); + result = result.state(State::List(false)); }, }; result.build() diff --git a/src/error/error.rs b/src/error/error.rs index 2ae68c6..84c4eca 100644 --- a/src/error/error.rs +++ b/src/error/error.rs @@ -49,7 +49,7 @@ impl Error { pub fn new() -> Self { Self { error_message: String::from(""), - return_state: State::List, + return_state: State::List(false), } } } diff --git a/src/external_editor/external_editor.rs b/src/external_editor/external_editor.rs index b7fd186..fe793e8 100644 --- a/src/external_editor/external_editor.rs +++ b/src/external_editor/external_editor.rs @@ -110,7 +110,7 @@ impl<'e> ExternalEditor<'e> { self.state = ExternalEditorState::Error; } else { - result = result.state(State::List); + result = result.state(State::List(false)); } result.build() } @@ -133,7 +133,7 @@ impl<'e> ExternalEditor<'e> { match input { Input::Resize => {}, _ => { - result = result.state(State::List); + result = result.state(State::List(false)); }, } result.build() diff --git a/src/git_interactive.rs b/src/git_interactive.rs index 5099751..3a86501 100644 --- a/src/git_interactive.rs +++ b/src/git_interactive.rs @@ -59,7 +59,7 @@ impl GitInteractive { lines, selected_commit_stats: None, selected_line_index: 1, - visual_index_start: 0, + visual_index_start: 1, }) } diff --git a/src/list/list.rs b/src/list/list.rs new file mode 100644 index 0000000..e94ad02 --- /dev/null +++ b/src/list/list.rs @@ -0,0 +1,306 @@ +use crate::action::Action; +use crate::config::Config; +use crate::constants::{ + LIST_FOOTER_COMPACT, + LIST_FOOTER_COMPACT_WIDTH, + LIST_FOOTER_FULL, + LIST_FOOTER_FULL_WIDTH, + LIST_HELP_LINES, + MINIMUM_FULL_WINDOW_WIDTH, + VISUAL_MODE_FOOTER_COMPACT, + VISUAL_MODE_FOOTER_COMPACT_WIDTH, + VISUAL_MODE_FOOTER_FULL, + VISUAL_MODE_FOOTER_FULL_WIDTH, + VISUAL_MODE_HELP_LINES, +}; +use crate::git_interactive::GitInteractive; +use crate::input::{Input, InputHandler}; +use crate::line::Line; +use crate::list::get_action_color; +use crate::process::{ExitStatus, HandleInputResult, HandleInputResultBuilder, ProcessModule, ProcessResult, State}; +use crate::scroll::ScrollPosition; +use crate::view::{LineSegment, View, ViewLine}; +use crate::window::WindowColor; +use std::cmp; + +#[derive(Debug, PartialEq)] +enum ListState { + Normal, + Visual, +} + +pub struct List<'l> { + config: &'l Config, + scroll_position: ScrollPosition, + state: ListState, +} + +impl<'l> ProcessModule for List<'l> { + #[allow(clippy::nonminimal_bool)] + fn render(&self, view: &View, git_interactive: &GitInteractive) { + let (view_width, view_height) = view.get_view_size(); + + let is_visual_mode = self.state == ListState::Visual; + let visual_index = git_interactive.get_visual_start_index() - 1; + + let mut view_lines: Vec<ViewLine> = vec![]; + + let selected_index = *git_interactive.get_selected_line_index() - 1; + + for (index, line) in git_interactive.get_lines().iter().enumerate() { + view_lines.push(ViewLine::new(self.get_todo_line_segments( + line, + selected_index == index, + is_visual_mode + && ((visual_index <= selected_index && index >= visual_index && index <= selected_index) + || (visual_index > selected_index && index >= selected_index && index <= visual_index)), + view_width, + ))); + } + + view.draw_title(true); + + view.draw_view_lines(view_lines, self.scroll_position.get_position(), view_height - 2); + + view.set_color(WindowColor::Foreground); + view.set_style(true, false, false); + if is_visual_mode { + if view_width >= VISUAL_MODE_FOOTER_FULL_WIDTH { + view.draw_str(VISUAL_MODE_FOOTER_FULL); + } + else if view_width >= VISUAL_MODE_FOOTER_COMPACT_WIDTH { + view.draw_str(VISUAL_MODE_FOOTER_COMPACT); + } + else { + view.draw_str("(Visual) Help: ?"); + } + } + else if view_width >= LIST_FOOTER_FULL_WIDTH { + view.draw_str(LIST_FOOTER_FULL); + } + else if view_width >= LIST_FOOTER_COMPACT_WIDTH { + view.draw_str(LIST_FOOTER_COMPACT); + } + else { + view.draw_str("Help: ?"); + } + view.set_style(false, false, false); + } +} + +impl<'l> List<'l> { + pub fn new(config: &'l Config) -> Self { + Self { + config, + scroll_position: ScrollPosition::new(2, 1, 1), + state: ListState::Normal, + } + } + + fn set_selected_line_action(&self, git_interactive: &mut GitInteractive, action: Action) { + git_interactive.set_selected_line_action(action); + if self.config.auto_select_next { + git_interactive.move_cursor_down(1); + } + } + + pub fn process_with_view(&mut self, git_interactive: &mut GitInteractive, view: &View) -> ProcessResult { + let (_, view_height) = view.get_view_size(); + let lines = git_interactive.get_lines(); + let selected_index = *git_interactive.get_selected_line_index() - 1; + self.scroll_position + .ensure_cursor_visible(selected_index, view_height, lines.len()); + ProcessResult::new() + } + + pub fn handle_input_with_view( + &mut self, + input_handler: &InputHandler, + git_interactive: &mut GitInteractive, + view: &View, + ) -> HandleInputResult + { + match self.state { + ListState::Normal => self.handle_normal_mode_input(input_handler, git_interactive, view), + ListState::Visual => self.handle_visual_mode_input(input_handler, git_interactive, view), + } + } + + fn handle_normal_mode_input( + &mut self, + input_handler: &InputHandler, + git_interactive: &mut GitInteractive, + view: &View, + ) -> HandleInputResult + { + let input = input_handler.get_input(); + let mut result = HandleInputResultBuilder::new(input); + match input { + Input::Help => { + view.update_help_top(false, true, LIST_HELP_LINES); + result = result.help(State::List(false)); + }, + Input::ShowCommit => { + if !git_interactive.get_selected_line_hash().is_empty() { + result = result.state(State::ShowCommit); + } + }, + Input::Abort => { + result = result.state(State::ConfirmAbort); + }, + Input::ForceAbort => { + git_interactive.clear(); + result = result.exit_status(ExitStatus::Good).state(State::Exiting); + }, + Input::Rebase => { + result = result.state(State::ConfirmRebase); + }, + Input::ForceRebase => { + result = result.exit_status(ExitStatus::Good).state(State::Exiting); + }, + Input::ActionBreak => git_interactive.toggle_break(), + Input::ActionDrop => self.set_selected_line_action(git_interactive, Action::Drop), + Input::ActionEdit => self.set_selected_line_action(git_interactive, Action::Edit), + Input::ActionFixup => self.set_selected_line_action(git_interactive, Action::Fixup), + Input::ActionPick => self.set_selected_line_action(git_interactive, Action::Pick), + Input::ActionReword => self.set_selected_line_action(git_interactive, Action::Reword), + Input::ActionSquash => self.set_selected_line_action(git_interactive, Action::Squash), + Input::Edit => { + if *git_interactive.get_selected_line_action() == Action::Exec { + result = result.state(State::Edit); + } + }, + Input::SwapSelectedDown => git_interactive.swap_selected_down(), + Input::SwapSelectedUp => git_interactive.swap_selected_up(), + Input::MoveCursorDown => git_interactive.move_cursor_down(1), + Input::MoveCursorUp => git_interactive.move_cursor_up(1), + Input::MoveCursorPageDown => git_interactive.move_cursor_down(5), + Input::MoveCursorPageUp => git_interactive.move_cursor_up(5), + Input::ToggleVisualMode => { + git_interactive.start_visual_mode(); + self.state = ListState::Visual; + result = result.state(State::List(true)); + }, + Input::OpenInEditor => result = result.state(State::ExternalEditor), + _ => {}, + } + result.build() + } + + fn handle_visual_mode_input( + &mut self, + input_handler: &InputHandler, + git_interactive: &mut GitInteractive, + view: &View, + ) -> HandleInputResult + { + let input = input_handler.get_input(); + let mut result = HandleInputResultBuilder::new(input); + match input { + Input::Help => { + view.update_help_top(false, true, VISUAL_MODE_HELP_LINES); + result = result.help(State::List(true)); + }, + Input::MoveCursorDown => { + git_interactive.move_cursor_down(1); + }, + Input::MoveCursorUp => { + git_interactive.move_cursor_up(1); + }, + Input::MoveCursorPageDown => { + git_interactive.move_cursor_down(5); + }, + Input::MoveCursorPageUp => { + git_interactive.move_cursor_up(5); + }, + Input::ActionDrop => git_interactive.set_visual_range_action(Action::Drop), + Input::ActionEdit => git_interactive.set_visual_range_action(Action::Edit), + Input::ActionFixup => git_interactive.set_visual_range_action(Action::Fixup), + Input::ActionPick => git_interactive.set_visual_range_action(Action::Pick), + Input::ActionReword => git_interactive.set_visual_range_action(Action::Reword), + Input::ActionSquash => git_interactive.set_visual_range_action(Action::Squash), + Input::SwapSelectedDown => git_interactive.swap_visual_range_down(), + Input::SwapSelectedUp => git_interactive.swap_visual_range_up(), + Input::ToggleVisualMode => { + self.state = ListState::Normal; + result = result.state(State::List(false)); + }, + _ => {}, + } + result.build() + } + + fn get_todo_line_segments( + &self, + line: &Line, + is_cursor_line: bool, + selected: bool, + view_width: usize, + ) -> Vec<LineSegment> + { + let mut segments: Vec<LineSegment> = vec![]; + + let action = line.get_action(); + + if view_width >= MINIMUM_FULL_WINDOW_WIDTH { + segments.push(LineSegment::new_with_color_and_style( + if is_cursor_line || selected { " > " } else { " " }, + WindowColor::Foreground, + !is_cursor_line && selected, + false, + false, + )); + + segments.push(LineSegment::new_with_color( + format!("{:6} ", action.as_string()).as_str(), + get_action_color(*action), + )); + + segments.push(LineSegment::new( + if *action == Action::Exec { + line.get_command().clone() + } + else if *action == Action::Break { + String::from(" ") + } + else { + let max_index = cmp::min(line.get_hash().len(), 8); + format!("{:8} ", line.get_hash()[0..max_index].to_string()) + } + .as_str(), + )); + } + else { + segments.push(LineSegment::new_with_color_and_style( + if is_cursor_line || selected { ">" } else { " " }, + WindowColor::Foreground, + !is_cursor_line && selected, + false, + false, + )); + + segments.push(LineSegment::new_with_color( + format!("{:1} ", line.get_action().to_abbreviation()).as_str(), + get_action_color(*action), + )); + + segments.push(LineSegment::new( + if *action == Action::Exec { + line.get_command().clone() + } + else if *action == Action::Break { + String::from(" ") + } + else { + let max_index = cmp::min(line.get_hash().len(), 3); + format!("{:3} ", line.get_hash()[0..max_index].to_string()) + } + .as_str(), + )); + } + if *action != Action::Exec && *action != Action::Break { + segments.push(LineSegment::new(line.get_comment().as_str())); + } + segments + } +} diff --git a/src/list/mod.rs b/src/list/mod.rs new file mode 100644 index 0000000..b428df8 --- /dev/null +++ b/src/list/mod.rs @@ -0,0 +1,6 @@ +#[allow(clippy::module_inception)] +mod list; +mod utils; + +pub use self::list::List; +pub use self::utils::get_action_color; diff --git a/src/list/utils.rs b/src/list/utils.rs new file mode 100644 index 0000000..8794ae7 --- /dev/null +++ b/src/list/utils.rs @@ -0,0 +1,15 @@ +use crate::action::Action; +use crate::window::WindowColor; + +pub fn get_action_color(action: Action) -> WindowColor { + match action { + Action::Break => WindowColor::ActionBreak, + Action::Drop => WindowColor::ActionDrop, + Action::Edit => WindowColor::ActionEdit, + Action::Exec => WindowColor::ActionExec, + Action::Fixup => WindowColor::ActionFixup, + Action::Pick => WindowColor::ActionPick, + Action::Reword => WindowColor::ActionReword, + Action::Squash => WindowColor::ActionSquash, + } +} diff --git a/src/main.rs b/src/main.rs index 70dc63b..335136f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ mod external_editor; mod git_interactive; mod input; mod line; +mod list; mod process; mod scroll; mod show_commit; diff --git a/src/process/process.rs b/src/process/process.rs index 5a5d00b..cf91d0d 100644 --- a/src/process/process.rs +++ b/src/process/process.rs @@ -14,7 +14,7 @@ impl<'r> Process<'r> { Self { application, exit_status: None, - state: RefCell::new(State::List), + state: RefCell::new(State::List(false)), } } diff --git a/src/process/state.rs b/src/process/state.rs index b286cb9..0162441 100644 --- a/src/process/state.rs +++ b/src/process/state.rs @@ -7,8 +7,7 @@ pub enum State { Exiting, ExternalEditor, Help(Box<State>), - List, + List(bool), // TODO refactor help to not require visual mode boolean ShowCommit, - VisualMode, WindowSizeError(Box<State>), } diff --git a/src/show_commit/show_commit.rs b/src/show_commit/show_commit.rs index 5ff8340..1d50ffa 100644 --- a/src/show_commit/show_commit.rs +++ b/src/show_commit/show_commit.rs @@ -27,7 +27,7 @@ impl ProcessModule for ShowCommit { 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 = result.error(e.as_str(), State::List(false)); } result.build() } @@ -168,7 +168,7 @@ impl ShowCommit { .scroll_up(window_height as usize, git_interactive.get_commit_stats_length()); }, _ => { - result = result.state(State::List); + result = result.state(State::List(false)); }, } result.build() diff --git a/src/view/view.rs b/src/view/view.rs index 7a22e89..eade0da 100644 --- a/src/view/view.rs +++ b/src/view/view.rs @@ -1,12 +1,6 @@ -use crate::action::Action; use crate::constants::{ HEIGHT_ERROR_MESSAGE, - LIST_FOOTER_COMPACT, - LIST_FOOTER_COMPACT_WIDTH, - LIST_FOOTER_FULL, - LIST_FOOTER_FULL_WIDTH, MINIMUM_COMPACT_WINDOW_WIDTH, - MINIMUM_FULL_WINDOW_WIDTH, MINIMUM_WINDOW_HEIGHT, MINIMUM_WINDOW_HEIGHT_ERROR_WIDTH, SHORT_ERROR_MESSAGE, @@ -17,21 +11,14 @@ use crate::constants::{ TITLE_LENGTH, TITLE_SHORT, TITLE_SHORT_LENGTH, - VISUAL_MODE_FOOTER_COMPACT, - VISUAL_MODE_FOOTER_COMPACT_WIDTH, - VISUAL_MODE_FOOTER_FULL, - VISUAL_MODE_FOOTER_FULL_WIDTH, }; -use crate::line::Line; use crate::scroll::{get_scroll_position, ScrollPosition}; use crate::view::{LineSegment, ViewLine}; use crate::window::Window; use crate::window::WindowColor; -use std::cmp; pub struct View<'v> { help_top: ScrollPosition, - main_top: ScrollPosition, window: &'v Window<'v>, } @@ -39,7 +26,6 @@ impl<'v> View<'v> { pub fn new(window: &'v Window) -> Self { Self { help_top: ScrollPosition::new(3, 6, 3), - main_top: ScrollPosition::new(2, 1, 1), window, } } @@ -196,164 +182,6 @@ impl<'v> View<'v> { } } - fn draw_visual_mode_footer(&self) { - let (window_width, _) = self.window.get_window_size(); - self.window.color(WindowColor::Foreground); - self.window.set_style(true, false, false); - if window_width >= VISUAL_MODE_FOOTER_FULL_WIDTH { - self.window.draw_str(VISUAL_MODE_FOOTER_FULL); - } - else if window_width >= VISUAL_MODE_FOOTER_COMPACT_WIDTH { - self.window.draw_str(VISUAL_MODE_FOOTER_COMPACT); - } - else { - self.window.draw_str("(Visual) Help: ?"); - } - self.window.set_style(false, false |