on master help sign in
Calculate the line that the range head is on correctly.
5841954Nathan Vegdahl
helix-core/src/selection.rs+12
@@ -73,6 +73,18 @@ impl Range {
73 std::cmp::max(self.anchor, self.head)
73 std::cmp::max(self.anchor, self.head)
74 }
74 }
75
75
76+ /// The line number that the head is on (using 1-width semantics).
77+ #[inline]
78+ #[must_use]
79+ pub fn head_line(&self, text: RopeSlice) -> usize {
80+ let head = if self.anchor < self.head {
81+ prev_grapheme_boundary(text, self.head)
82+ } else {
83+ self.head
84+ };
85+ text.char_to_line(head)
86+ }
87+
76 /// The (inclusive) range of lines that the range overlaps.
88 /// The (inclusive) range of lines that the range overlaps.
77 #[inline]
89 #[inline]
78 #[must_use]
90 #[must_use]
helix-term/src/commands.rs+12−23
@@ -396,19 +396,14 @@ fn goto_line_end(cx: &mut Context) {
396 view.id,
396 view.id,
397 doc.selection(view.id).clone().transform(|range| {
397 doc.selection(view.id).clone().transform(|range| {
398 let text = doc.text().slice(..);
398 let text = doc.text().slice(..);
399−
399+ let line = range.head_line(text);
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
400
407 let mut pos = line_end_char_index(&text, line);
401 let mut pos = line_end_char_index(&text, line);
408 if doc.mode != Mode::Select {
402 if doc.mode != Mode::Select {
409 pos = graphemes::prev_grapheme_boundary(text, pos);
403 pos = graphemes::prev_grapheme_boundary(text, pos);
410 }
404 }
405+
411− pos = head.max(pos).max(text.line_to_char(line));
406+ pos = range.head.max(pos).max(text.line_to_char(line));
412
407
413 range.put(text, pos, doc.mode == Mode::Select)
408 range.put(text, pos, doc.mode == Mode::Select)
414 }),
409 }),
@@ -422,13 +417,7 @@ fn goto_line_end_newline(cx: &mut Context) {
422 view.id,
417 view.id,
423 doc.selection(view.id).clone().transform(|range| {
418 doc.selection(view.id).clone().transform(|range| {
424 let text = doc.text().slice(..);
419 let text = doc.text().slice(..);
425−
420+ let line = range.head_line(text);
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
421
433 let mut pos = text.line_to_char((line + 1).min(text.len_lines()));
422 let mut pos = text.line_to_char((line + 1).min(text.len_lines()));
434 if doc.mode != Mode::Select {
423 if doc.mode != Mode::Select {
@@ -445,7 +434,7 @@ fn goto_line_start(cx: &mut Context) {
445 view.id,
434 view.id,
446 doc.selection(view.id).clone().transform(|range| {
435 doc.selection(view.id).clone().transform(|range| {
447 let text = doc.text().slice(..);
436 let text = doc.text().slice(..);
448− let line = text.char_to_line(range.head);
437+ let line = range.head_line(text);
449
438
450 // adjust to start of the line
439 // adjust to start of the line
451 let pos = text.line_to_char(line);
440 let pos = text.line_to_char(line);
@@ -460,10 +449,10 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
460 view.id,
449 view.id,
461 doc.selection(view.id).clone().transform(|range| {
450 doc.selection(view.id).clone().transform(|range| {
462 let text = doc.text().slice(..);
451 let text = doc.text().slice(..);
463− let line_idx = text.char_to_line(range.head);
452+ let line = range.head_line(text);
464
453
465− if let Some(pos) = find_first_non_whitespace_char(text.line(line_idx)) {
454+ if let Some(pos) = find_first_non_whitespace_char(text.line(line)) {
466− let pos = pos + text.line_to_char(line_idx);
455+ let pos = pos + text.line_to_char(line);
467 range.put(text, pos, doc.mode == Mode::Select)
456 range.put(text, pos, doc.mode == Mode::Select)
468 } else {
457 } else {
469 range
458 range
@@ -2212,9 +2201,9 @@ fn append_to_line(cx: &mut Context) {
2212 doc.set_selection(
2201 doc.set_selection(
2213 view.id,
2202 view.id,
2214 doc.selection(view.id).clone().transform(|range| {
2203 doc.selection(view.id).clone().transform(|range| {
2215− let text = &doc.text().slice(..);
2204+ let text = doc.text().slice(..);
2216− let line = text.char_to_line(range.head);
2205+ let line = range.head_line(text);
2217− let pos = line_end_char_index(text, line);
2206+ let pos = line_end_char_index(&text, line);
2218 Range::new(pos, pos)
2207 Range::new(pos, pos)
2219 }),
2208 }),
2220 );
2209 );
@@ -2274,7 +2263,7 @@ fn open(cx: &mut Context, open: Open) {
2274 let mut offs = 0;
2263 let mut offs = 0;
2275
2264
2276 let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
2265 let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
2277− let line = text.char_to_line(range.head);
2266+ let line = range.head_line(text);
2278
2267
2279 let line = match open {
2268 let line = match open {
2280 // adjust position to the end of the line (next line - 1)
2269 // adjust position to the end of the line (next line - 1)