summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/git_interactive.rs59
-rw-r--r--src/list/mod.rs65
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;