aboutsummaryrefslogtreecommitdiff
path: root/src/selection.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/selection.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/selection.rs b/src/selection.rs
index 9be01dd..375072c 100644
--- a/src/selection.rs
+++ b/src/selection.rs
@@ -213,6 +213,78 @@ impl Selection {
self.select_range(start, end);
}
+ /// Updates the current selection by setting a new end point, either to the start of the
+ /// previous word, or to the next one's end.
+ pub fn change_selection_by_word(
+ &mut self,
+ new_end: SelectionEnd,
+ paragraph: &Paragraph,
+ ) {
+ let (base_word_start, base_word_end) = {
+ if self.direction == Direction::Right {
+ let value = Value::new(
+ paragraph.buffer().lines[self.start.line].text(),
+ );
+
+ let end = SelectionEnd::new(
+ self.start.line,
+ value.next_end_of_word(self.start.index),
+ );
+
+ (self.start, end)
+ } else {
+ let value =
+ Value::new(paragraph.buffer().lines[self.end.line].text());
+
+ let start = SelectionEnd::new(
+ self.end.line,
+ value.previous_start_of_word(self.end.index),
+ );
+
+ (start, self.end)
+ }
+ };
+
+ let value = Value::new(paragraph.buffer().lines[new_end.line].text());
+
+ let (start, end) = if new_end < self.start {
+ self.direction = Direction::Left;
+
+ let start = SelectionEnd::new(
+ new_end.line,
+ value.previous_start_of_word(new_end.index),
+ );
+
+ (start, base_word_end)
+ } else if new_end > self.end {
+ self.direction = Direction::Right;
+
+ let end = SelectionEnd::new(
+ new_end.line,
+ value.next_end_of_word(new_end.index),
+ );
+
+ (base_word_start, end)
+ } else if self.direction == Direction::Right {
+ let end = SelectionEnd::new(
+ new_end.line,
+ value.next_end_of_word(new_end.index),
+ );
+
+ (base_word_start, end.max(base_word_end))
+ } else {
+ let start = SelectionEnd::new(
+ new_end.line,
+ value.previous_start_of_word(new_end.index),
+ );
+
+ (start.min(base_word_start), base_word_end)
+ };
+
+ self.moving_line_index = None;
+ self.select_range(start, end);
+ }
+
/// Updates the current selection by setting a new end point, either to the end of a following
/// line, or the beginning of a previous one.
pub fn change_selection_by_line(
@@ -246,6 +318,7 @@ impl Selection {
(start, end)
} else {
let start = SelectionEnd::new(new_line, 0);
+
let end = if self.direction == old_direction {
self.end
} else {