Fix various bugs related to goto-end-of-line command.

This also fixes a bug with `Selection::normalize()`, that could
result in an out-of-bounds primary index.
pull/376/head
Nathan Vegdahl 3 years ago
parent e8a3980e46
commit 1c6b5581f0

@ -357,14 +357,14 @@ impl Selection {
let mut prev_i = 0; let mut prev_i = 0;
for i in 1..self.ranges.len() { for i in 1..self.ranges.len() {
if self.ranges[prev_i].overlaps(&self.ranges[i]) { if self.ranges[prev_i].overlaps(&self.ranges[i]) {
if i == self.primary_index {
self.primary_index = prev_i;
}
self.ranges[prev_i] = self.ranges[prev_i].merge(self.ranges[i]); self.ranges[prev_i] = self.ranges[prev_i].merge(self.ranges[i]);
} else { } else {
prev_i += 1; prev_i += 1;
self.ranges[prev_i] = self.ranges[i]; self.ranges[prev_i] = self.ranges[i];
} }
if i == self.primary_index {
self.primary_index = prev_i;
}
} }
self.ranges.truncate(prev_i + 1); self.ranges.truncate(prev_i + 1);

@ -396,11 +396,19 @@ fn goto_line_end(cx: &mut Context) {
view.id, view.id,
doc.selection(view.id).clone().transform(|range| { doc.selection(view.id).clone().transform(|range| {
let text = doc.text().slice(..); let text = doc.text().slice(..);
let line = text.char_to_line(range.head);
let pos = line_end_char_index(&text, line); let head = if range.anchor < range.head {
let pos = graphemes::nth_prev_grapheme_boundary(text, pos, 1); graphemes::prev_grapheme_boundary(text, range.head)
let pos = range.head.max(pos).max(text.line_to_char(line)); } else {
range.head
};
let line = text.char_to_line(head);
let mut pos = line_end_char_index(&text, line);
if doc.mode != Mode::Select {
pos = graphemes::prev_grapheme_boundary(text, pos);
}
pos = head.max(pos).max(text.line_to_char(line));
range.put(text, pos, doc.mode == Mode::Select) range.put(text, pos, doc.mode == Mode::Select)
}), }),
@ -414,9 +422,18 @@ fn goto_line_end_newline(cx: &mut Context) {
view.id, view.id,
doc.selection(view.id).clone().transform(|range| { doc.selection(view.id).clone().transform(|range| {
let text = doc.text().slice(..); let text = doc.text().slice(..);
let line = text.char_to_line(range.head);
let pos = line_end_char_index(&text, line); let head = if range.anchor < range.head {
graphemes::prev_grapheme_boundary(text, range.head)
} else {
range.head
};
let line = text.char_to_line(head);
let mut pos = text.line_to_char((line + 1).min(text.len_lines()));
if doc.mode != Mode::Select {
pos = graphemes::prev_grapheme_boundary(text, pos);
}
range.put(text, pos, doc.mode == Mode::Select) range.put(text, pos, doc.mode == Mode::Select)
}), }),
); );

Loading…
Cancel
Save