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.
This commit is contained in:
parent
e8a3980e46
commit
1c6b5581f0
2 changed files with 26 additions and 9 deletions
|
@ -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…
Add table
Reference in a new issue