diff --git a/src/action.rs b/src/action.rs index 46c7c8e..5131ab6 100644 --- a/src/action.rs +++ b/src/action.rs @@ -47,6 +47,7 @@ pub enum Action { ExtendPreviousWordStart, CollapseSelection, + FlipSelections, ExtendLineBelow, ExtendLineAbove, @@ -126,6 +127,7 @@ impl Buffer { Action::ExtendPreviousWordStart => self.extend_previous_word_start(window_size), Action::CollapseSelection => self.collapse_selection(), + Action::FlipSelections => self.flip_selection(), Action::ExtendLineBelow => self.extend_line_below(window_size), Action::ExtendLineAbove => self.extend_line_above(window_size), @@ -391,6 +393,14 @@ impl Buffer { } } + fn flip_selection(&mut self) { + self.primary_cursor.flip(); + + for cursor in &mut self.cursors { + cursor.flip(); + } + } + fn extend_line_below(&mut self, window_size: WindowSize) { let max_contents_index = self.max_contents_index(); self.change_all_cursors(|cursor| cursor.extend_line_below(max_contents_index)); @@ -495,6 +505,8 @@ impl Buffer { self.cursors.sort_by_key(|cursor| cursor.head); self.combine_cursors_if_overlapping(); + + self.rotate_selections_forward(); } fn rotate_selections_backward(&mut self) { diff --git a/src/config.rs b/src/config.rs index 41115d8..bf2fd8d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -130,6 +130,7 @@ impl Default for Config { ("b".try_into().unwrap(), Action::MovePreviousWordStart), (";".try_into().unwrap(), Action::CollapseSelection), + ("A-;".try_into().unwrap(), Action::FlipSelections), ("x".try_into().unwrap(), Action::ExtendLineBelow), ("X".try_into().unwrap(), Action::ExtendLineAbove), @@ -191,6 +192,7 @@ impl Default for Config { ("b".try_into().unwrap(), Action::ExtendPreviousWordStart), (";".try_into().unwrap(), Action::CollapseSelection), + ("A-;".try_into().unwrap(), Action::FlipSelections), ("x".try_into().unwrap(), Action::ExtendLineBelow), ("X".try_into().unwrap(), Action::ExtendLineAbove), diff --git a/src/cursor.rs b/src/cursor.rs index 4c81a59..d1ea78c 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -51,6 +51,10 @@ impl Cursor { self.tail = self.head; } + pub const fn flip(&mut self) { + swap(&mut self.head, &mut self.tail); + } + // TODO: in visual mode, should only clamp head pub fn clamp(&mut self, scroll_position: usize, screen_size: usize) { let max_row = scroll_position + screen_size - 1;