Skip to content

Commit

Permalink
Added Movement::StartOfDocument; Movement::EndOfDocument.
Browse files Browse the repository at this point in the history
  • Loading branch information
sysint64 committed Sep 3, 2020
1 parent f827c57 commit 42d5381
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ You can find its changes [documented below](#060---2020-06-01).
- `request_update` in `EventCtx`. ([#1128] by [@raphlinus])
- `ExtEventSink`s can now be obtained from widget methods. ([#1152] by [@jneem])
- 'Scope' widget to allow encapsulation of reactive state. ([#1151] by [@rjwittams])
- `Movement::StartOfDocument`, `Movement::EndOfDocument`. ([#1092] by [@sysint64])

### Changed

Expand Down Expand Up @@ -406,6 +407,7 @@ Last release without a changelog :(
[#1152]: https://github.com/linebender/druid/pull/1152
[#1157]: https://github.com/linebender/druid/pull/1157
[#1172]: https://github.com/linebender/druid/pull/1157
[#1092]: https://github.com/linebender/druid/pull/1092

[Unreleased]: https://github.com/linebender/druid/compare/v0.6.0...master
[0.6.0]: https://github.com/linebender/druid/compare/v0.5.0...v0.6.0
Expand Down
66 changes: 66 additions & 0 deletions druid/src/text/editable_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ pub trait EditableText: Sized {
/// Get the next codepoint offset from the given offset, if it exists.
fn next_codepoint_offset(&self, offset: usize) -> Option<usize>;

/// Get the line beginning offset from the given offset, if it exists.
fn left_end_of_line(&self, offset: usize) -> usize;

/// Get the line ending offset from the given offset, if it exists.
fn right_end_of_line(&self, offset: usize) -> usize;

/// Returns `true` if this text has 0 length.
fn is_empty(&self) -> bool;

Expand Down Expand Up @@ -156,6 +162,32 @@ impl EditableText for String {
fn from_str(s: &str) -> Self {
s.to_string()
}

fn left_end_of_line(&self, from: usize) -> usize {
let mut offset = from;

for byte in self.get(0..from).unwrap_or("").bytes().rev() {
if byte == 0x0a {
return offset;
}
offset -= 1;
}

0
}

fn right_end_of_line(&self, from: usize) -> usize {
let mut offset = from;

for char in self.get(from..).unwrap_or("").bytes() {
if char == 0x0a {
return offset;
}
offset += 1;
}

self.len()
}
}

/// A cursor with convenience functions for moving through EditableText.
Expand Down Expand Up @@ -410,4 +442,38 @@ mod tests {
assert_eq!(Some(35), a.next_word_offset(26));
assert_eq!(Some(35), a.next_word_offset(35));
}

#[test]
fn left_end_of_line() {
let a = String::from("Technically\na word:\n ৬藏A\u{030a}\n\u{110b}\u{1161}");
assert_eq!(0, a.left_end_of_line(0));
assert_eq!(0, a.left_end_of_line(11));
assert_eq!(12, a.left_end_of_line(12));
assert_eq!(12, a.left_end_of_line(13));
assert_eq!(20, a.left_end_of_line(21));
assert_eq!(31, a.left_end_of_line(31));
assert_eq!(31, a.left_end_of_line(34));

let b = String::from("Technically a word: ৬藏A\u{030a}\u{110b}\u{1161}");
assert_eq!(0, b.left_end_of_line(0));
assert_eq!(0, b.left_end_of_line(11));
assert_eq!(0, b.left_end_of_line(13));
assert_eq!(0, b.left_end_of_line(21));
}

#[test]
fn right_end_of_line() {
let a = String::from("Technically\na word:\n ৬藏A\u{030a}\n\u{110b}\u{1161}");
assert_eq!(11, a.right_end_of_line(0));
assert_eq!(11, a.right_end_of_line(11));
assert_eq!(19, a.right_end_of_line(13));
assert_eq!(30, a.right_end_of_line(21));
assert_eq!(a.len(), a.right_end_of_line(31));

let b = String::from("Technically a word: ৬藏A\u{030a}\u{110b}\u{1161}");
assert_eq!(b.len(), b.right_end_of_line(0));
assert_eq!(b.len(), b.right_end_of_line(11));
assert_eq!(b.len(), b.right_end_of_line(13));
assert_eq!(b.len(), b.right_end_of_line(19));
}
}
11 changes: 9 additions & 2 deletions druid/src/text/movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ pub enum Movement {
LeftOfLine,
/// Move to right end of visible line.
RightOfLine,
/// Move to the beginning of the document
StartOfDocument,
/// Move to the end of the document
EndOfDocument,
}

/// Compute the result of movement on a selection .
Expand All @@ -51,8 +55,11 @@ pub fn movement(m: Movement, s: Selection, text: &impl EditableText, modify: boo
}
}

Movement::LeftOfLine => 0,
Movement::RightOfLine => text.len(),
Movement::LeftOfLine => text.left_end_of_line(s.end),
Movement::RightOfLine => text.right_end_of_line(s.end),

Movement::StartOfDocument => 0,
Movement::EndOfDocument => text.len(),

Movement::LeftWord => {
if s.is_caret() || modify {
Expand Down

0 comments on commit 42d5381

Please sign in to comment.