on master help sign in
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.

commit1c6b5581f01371a00dc7f6f6e1720ad8af61ec7a authorNathan Vegdahl <cessen@cessen.com> dateTue 20 Jul 2021, 11:58 (5 years ago) parente8a3980
2 files changed+26−9
helix-core/src/selection.rs+3−3 helix-term/src/commands.rs+23−6
helix-core/src/selection.rs+3−3
@@ -357,14 +357,14 @@ impl Selection {
357357 let mut prev_i = 0;
358358 for i in 1..self.ranges.len() {
359359 if self.ranges[prev_i].overlaps(&self.ranges[i]) {
360− if i == self.primary_index {
361− self.primary_index = prev_i;
362− }
363360 self.ranges[prev_i] = self.ranges[prev_i].merge(self.ranges[i]);
364361 } else {
365362 prev_i += 1;
366363 self.ranges[prev_i] = self.ranges[i];
367364 }
365+ if i == self.primary_index {
366+ self.primary_index = prev_i;
367+ }
368368 }
369369
370370 self.ranges.truncate(prev_i + 1);
helix-term/src/commands.rs+23−6
@@ -396,11 +396,19 @@ fn goto_line_end(cx: &mut Context) {
396396 view.id,
397397 doc.selection(view.id).clone().transform(|range| {
398398 let text = doc.text().slice(..);
399− let line = text.char_to_line(range.head);
400399
401− let pos = line_end_char_index(&text, line);
402− let pos = graphemes::nth_prev_grapheme_boundary(text, pos, 1);
403− let pos = range.head.max(pos).max(text.line_to_char(line));
400+ let head = if range.anchor < range.head {
401+ graphemes::prev_grapheme_boundary(text, range.head)
402+ } else {
403+ range.head
404+ };
405+ let line = text.char_to_line(head);
406+
407+ let mut pos = line_end_char_index(&text, line);
408+ if doc.mode != Mode::Select {
409+ pos = graphemes::prev_grapheme_boundary(text, pos);
410+ }
411+ pos = head.max(pos).max(text.line_to_char(line));
404412
405413 range.put(text, pos, doc.mode == Mode::Select)
406414 }),
@@ -414,9 +422,18 @@ fn goto_line_end_newline(cx: &mut Context) {
414422 view.id,
415423 doc.selection(view.id).clone().transform(|range| {
416424 let text = doc.text().slice(..);
417− let line = text.char_to_line(range.head);
418425
419− let pos = line_end_char_index(&text, line);
426+ let head = if range.anchor < range.head {
427+ graphemes::prev_grapheme_boundary(text, range.head)
428+ } else {
429+ range.head
430+ };
431+ let line = text.char_to_line(head);
432+
433+ let mut pos = text.line_to_char((line + 1).min(text.len_lines()));
434+ if doc.mode != Mode::Select {
435+ pos = graphemes::prev_grapheme_boundary(text, pos);
436+ }
420437 range.put(text, pos, doc.mode == Mode::Select)
421438 }),
422439 );