@@ -32,60 +32,31 @@ pub fn move_horizontally(
32 count: usize,
32 count: usize,
33 behaviour: Movement,
33 behaviour: Movement,
34) -> Range {
34) -> Range {
35− match (behaviour, dir) {
36− (Movement::Move, Direction::Backward) => {
37− let count = if range.anchor < range.head {
42− let pos = nth_prev_grapheme_boundary(slice, range.head, count);
45− (Movement::Move, Direction::Forward) => {
46− let count = if range.anchor < range.head {
51− let pos = nth_next_grapheme_boundary(slice, range.head, count);
54− (Movement::Extend, Direction::Backward) => {
35+ use Movement::Extend;
55− // Ensure a valid initial selection state.
56− let range = range.min_width_1(slice);
58− // Do the main movement.
59− let mut head = nth_prev_grapheme_boundary(slice, range.head, count);
60− let mut anchor = range.anchor;
62− // If the head and anchor crossed over each other, we need to
63− // fiddle around to make it behave like a 1-wide cursor.
64− if head <= anchor && range.head > range.anchor {
65− anchor = next_grapheme_boundary(slice, anchor);
66− head = prev_grapheme_boundary(slice, head);
69− Range::new(anchor, head)
37+ // Shift back one grapheme if needed, to account for
70− }
38+ // the cursor being visually 1-width.
71− (Movement::Extend, Direction::Forward) => {
72− // Ensure a valid initial selection state.
73− let range = range.min_width_1(slice);
75− // Do the main movement.
76− let mut head = nth_next_grapheme_boundary(slice, range.head, count);
77− let mut anchor = range.anchor;
79− // If the head and anchor crossed over each other, we need to
80− // fiddle around to make it behave like a 1-wide cursor.
81− if head >= anchor && range.head < range.anchor {
39+ let pos = if range.head > range.anchor {
82− anchor = prev_grapheme_boundary(slice, anchor);
40+ prev_grapheme_boundary(slice, range.head)
83− head = next_grapheme_boundary(slice, head);
41+ } else {
86− Range::new(anchor, head)
45+ // Compute the new position.
46+ let mut new_pos = if dir == Direction::Backward {
47+ nth_prev_grapheme_boundary(slice, pos, count)
49+ nth_next_grapheme_boundary(slice, pos, count)
52+ // Shift forward one grapheme if needed, for the
53+ // visual 1-width cursor.
54+ if behaviour == Extend && new_pos >= range.anchor {
55+ new_pos = next_grapheme_boundary(slice, new_pos);
58+ // Compute the final new range.
59+ range.put(slice, behaviour == Extend, new_pos)
91pub fn move_vertically(
62pub fn move_vertically(
@@ -135,19 +106,9 @@ pub fn move_vertically(
138− let new_anchor = if range.anchor <= range.head && range.anchor > new_head {
109+ let mut new_range = range.put(slice, true, new_head);
139− next_grapheme_boundary(slice, range.anchor)
140− } else if range.anchor > range.head && range.anchor < new_head {
141− prev_grapheme_boundary(slice, range.anchor)
149− horiz: Some(horiz),
110+ new_range.horiz = Some(horiz);