diff options
-rw-r--r-- | src/git_interactive.rs | 59 | ||||
-rw-r--r-- | src/list/mod.rs | 65 |
2 files changed, 68 insertions, 56 deletions
diff --git a/src/git_interactive.rs b/src/git_interactive.rs index 54b2acb..d440fe0 100644 --- a/src/git_interactive.rs +++ b/src/git_interactive.rs @@ -75,6 +75,10 @@ impl GitInteractive { self.selected_line_index = selected_line_index; } + pub(crate) fn set_visual_index(&mut self, visual_index: usize) { + self.visual_index_start = Some(visual_index); + } + pub(crate) fn start_visual_mode(&mut self) { self.visual_index_start = Some(self.selected_line_index); } @@ -83,55 +87,8 @@ impl GitInteractive { self.visual_index_start = None; } - pub(crate) fn swap_range_up(&mut self) { - let end_index = self.visual_index_start.unwrap_or(self.selected_line_index); - let start_index = self.selected_line_index; - - if end_index == 1 || start_index == 1 { - return; - } - - let range = if end_index <= start_index { - end_index..=start_index - } - else { - start_index..=end_index - }; - - for index in range { - self.lines.swap(index - 1, index - 2); - } - - if let Some(visual_index_start) = self.visual_index_start { - self.visual_index_start = Some(visual_index_start - 1); - } - self.selected_line_index -= 1; - } - - pub(crate) fn swap_range_down(&mut self) { - let end_index = self.visual_index_start.unwrap_or(self.selected_line_index); - let start_index = self.selected_line_index; - - if end_index == self.lines.len() || start_index == self.lines.len() { - return; - } - - let range = if end_index <= start_index { - end_index..=start_index - } - else { - start_index..=end_index - }; - - for index in range.rev() { - self.lines.swap(index - 1, index); - } - - if let Some(visual_index_start) = self.visual_index_start { - self.visual_index_start = Some(visual_index_start + 1); - } - - self.selected_line_index += 1; + pub(crate) fn swap_lines(&mut self, a: usize, b: usize) { + self.lines.swap(a, b); } pub(crate) fn edit_selected_line(&mut self, content: &str) { @@ -177,8 +134,8 @@ impl GitInteractive { self.selected_line_index } - pub(crate) fn get_visual_start_index(&self) -> usize { - self.visual_index_start.unwrap_or(self.selected_line_index) + pub(crate) const fn get_visual_start_index(&self) -> Option<usize> { + self.visual_index_start } pub(crate) fn get_filepath(&self) -> &str { diff --git a/src/list/mod.rs b/src/list/mod.rs index b812b14..feff5cb 100644 --- a/src/list/mod.rs +++ b/src/list/mod.rs @@ -39,7 +39,10 @@ impl<'l> ProcessModule for List<'l> { self.view_data.clear(); let is_visual_mode = self.state == ListState::Visual; - let visual_index = git_interactive.get_visual_start_index() - 1; + let visual_index = git_interactive + .get_visual_start_index() + .unwrap_or_else(|| git_interactive.get_selected_line_index()) + - 1; let selected_index = git_interactive.get_selected_line_index() - 1; for (index, line) in git_interactive.get_lines().iter().enumerate() { @@ -140,6 +143,58 @@ impl<'l> List<'l> { } } + pub(crate) fn swap_range_up(git_interactive: &mut GitInteractive) { + let start_index = git_interactive.get_selected_line_index(); + let end_index = git_interactive.get_visual_start_index().unwrap_or(start_index); + + if end_index == 1 || start_index == 1 { + return; + } + + let range = if end_index <= start_index { + end_index..=start_index + } + else { + start_index..=end_index + }; + + for index in range { + git_interactive.swap_lines(index - 1, index - 2); + } + + if let Some(visual_index_start) = git_interactive.get_visual_start_index() { + git_interactive.set_visual_index(visual_index_start - 1); + } + Self::move_cursor_up(git_interactive, 1); + } + + pub(crate) fn swap_range_down(git_interactive: &mut GitInteractive) { + let start_index = git_interactive.get_selected_line_index(); + let end_index = git_interactive.get_visual_start_index().unwrap_or(start_index); + let lines_length = git_interactive.get_lines().len(); + + if end_index == lines_length || start_index == lines_length { + return; + } + + let range = if end_index <= start_index { + end_index..=start_index + } + else { + start_index..=end_index + }; + + for index in range.rev() { + git_interactive.swap_lines(index - 1, index); + } + + if let Some(visual_index_start) = git_interactive.get_visual_start_index() { + git_interactive.set_visual_index(visual_index_start + 1); + } + + Self::move_cursor_down(git_interactive, 1); + } + fn handle_normal_mode_input( &mut self, input: Input, @@ -190,8 +245,8 @@ impl<'l> List<'l> { result = result.state(State::Edit); } }, - Input::SwapSelectedDown => git_interactive.swap_range_down(), - Input::SwapSelectedUp => git_interactive.swap_range_up(), + Input::SwapSelectedDown => Self::swap_range_down(git_interactive), + Input::SwapSelectedUp => Self::swap_range_up(git_interactive), Input::ToggleVisualMode => { git_interactive.start_visual_mode(); self.state = ListState::Visual; @@ -232,8 +287,8 @@ impl<'l> List<'l> { Input::ActionPick => self.set_selected_line_action(git_interactive, Action::Pick, false), Input::ActionReword => self.set_selected_line_action(git_interactive, Action::Reword, false), Input::ActionSquash => self.set_selected_line_action(git_interactive, Action::Squash, false), - Input::SwapSelectedDown => git_interactive.swap_range_down(), - Input::SwapSelectedUp => git_interactive.swap_range_up(), + Input::SwapSelectedDown => Self::swap_range_down(git_interactive), + Input::SwapSelectedUp => Self::swap_range_up(git_interactive), Input::ToggleVisualMode => { git_interactive.end_visual_mode(); self.state = ListState::Normal; |