on master help sign in
Collect some common patterns into methods on `Range`.
commit0883b4fae03343978e61fc377775d7ba93f86b40 authorNathan Vegdahl <cessen@cessen.com> dateMon 26 Jul 2021, 08:40 (5 years ago) parentf96b8b7
8 files changed+155−163
helix-core/src/movement.rs+11−39 helix-core/src/selection.rs+35−45 helix-core/src/textobject.rs+5−10 helix-term/src/commands.rs+65−59 helix-term/src/ui/completion.rs+16−4 helix-term/src/ui/editor.rs+11−3 helix-view/src/editor.rs+8−2 helix-view/src/view.rs+4−1
helix-core/src/movement.rs+11−39
@@ -31,15 +31,7 @@ pub fn move_horizontally(
3131 count: usize,
3232 behaviour: Movement,
3333) -> Range {
34− use Movement::Extend;
35−
36− // Shift back one grapheme if needed, to account for
37− // the cursor being visually 1-width.
38− let pos = if range.head > range.anchor {
39− prev_grapheme_boundary(slice, range.head)
40− } else {
41− range.head
42− };
34+ let pos = range.cursor(slice);
4335
4436 // Compute the new position.
4537 let new_pos = if dir == Direction::Backward {
@@ -49,11 +41,7 @@ pub fn move_horizontally(
4941 };
5042
5143 // Compute the final new range.
52− if behaviour == Extend {
53− range.move_head(slice, new_pos, true)
54− } else {
55− Range::point(new_pos)
56− }
44+ range.put_cursor(slice, new_pos, behaviour == Movement::Extend)
5745}
5846
5947pub fn move_vertically(
@@ -63,13 +51,7 @@ pub fn move_vertically(
6351 count: usize,
6452 behaviour: Movement,
6553) -> Range {
66− // Shift back one grapheme if needed, to account for
67− // the cursor being visually 1-width.
68− let pos = if range.head > range.anchor {
69− prev_grapheme_boundary(slice, range.head)
70− } else {
71− range.head
72− };
54+ let pos = range.cursor(slice);
7355
7456 // Compute the current position's 2d coordinates.
7557 let Position { row, col } = coords_at_pos(slice, pos);
@@ -89,24 +71,14 @@ pub fn move_vertically(
8971 )
9072 };
9173
92− // Compute the new range according to the type of movement.
93− match behaviour {
94− Movement::Move => Range {
95− anchor: new_pos,
96− head: new_pos,
97− horiz: Some(horiz),
98− },
99−
100− Movement::Extend => {
101− if slice.line(new_row).len_chars() > 0 {
102− let mut new_range = range.move_head(slice, new_pos, true);
103− new_range.horiz = Some(horiz);
104− new_range
105− } else {
106− range
107− }
108− }
74+ // Special-case to avoid moving to the end of the last non-empty line.
75+ if behaviour == Movement::Extend && slice.line(new_row).len_chars() == 0 {
76+ return range;
10977 }
78+
79+ let mut new_range = range.put_cursor(slice, new_pos, behaviour == Movement::Extend);
80+ new_range.horiz = Some(horiz);
81+ new_range
11082}
11183
11284pub fn move_next_word_start(slice: RopeSlice, range: Range, count: usize) -> Range {
@@ -153,7 +125,7 @@ fn word_move(slice: RopeSlice, range: Range, count: usize, target: WordMotionTar
153125 // Prepare the range appropriately based on the target movement
154126 // direction. This is addressing two things at once:
155127 //
156− // 1. 1-width range sementics.
128+ // 1. Block-cursor semantics.
157129 // 2. The anchor position being irrelevant to the output result.
158130 #[allow(clippy::collapsible_else_if)] // Makes the structure clearer in this case.
159131 let start_range = if is_prev {
helix-core/src/selection.rs+35−45
@@ -73,16 +73,11 @@ impl Range {
7373 std::cmp::max(self.anchor, self.head)
7474 }
7575
76− /// The line number that the head is on (using 1-width semantics).
76+ /// The line number that the block-cursor is on.
7777 #[inline]
7878 #[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)
79+ pub fn cursor_line(&self, text: RopeSlice) -> usize {
80+ text.char_to_line(self.cursor(text))
8681 }
8782
8883 /// The (inclusive) range of lines that the range overlaps.
@@ -248,29 +243,44 @@ impl Range {
248243 }
249244 }
250245
251− /// Moves the head of the `Range` to `char_idx`, adjusting the anchor
252− /// as needed to preserve 1-width range semantics.
246+ /// Gets the left-side position of the block cursor.
247+ #[must_use]
248+ #[inline]
249+ pub fn cursor(self, text: RopeSlice) -> usize {
250+ if self.head > self.anchor {
251+ prev_grapheme_boundary(text, self.head)
252+ } else {
253+ self.head
254+ }
255+ }
256+
257+ /// Puts the left side of the block cursor at `char_idx`, optionally extending.
253258 ///
254− /// `block_cursor` specifies whether it should treat `char_idx` as a block
255− /// cursor position or as a range-end position.
259+ /// This follows "1-width" semantics, and therefore does a combination of anchor
260+ /// and head moves to behave as if both the front and back of the range are 1-width
261+ /// blocks
256262 ///
257263 /// This method assumes that the range and `char_idx` are already properly
258264 /// grapheme-aligned.
259265 #[must_use]
260266 #[inline]
261− pub fn move_head(self, text: RopeSlice, char_idx: usize, block_cursor: bool) -> Range {
262− let anchor = if self.head >= self.anchor && char_idx < self.anchor {
263− next_grapheme_boundary(text, self.anchor)
264− } else if self.head < self.anchor && char_idx >= self.anchor {
265− prev_grapheme_boundary(text, self.anchor)
266− } else {
267− self.anchor
268− };
267+ pub fn put_cursor(self, text: RopeSlice, char_idx: usize, extend: bool) -> Range {
268+ if extend {
269+ let anchor = if self.head >= self.anchor && char_idx < self.anchor {
270+ next_grapheme_boundary(text, self.anchor)
271+ } else if self.head < self.anchor && char_idx >= self.anchor {
272+ prev_grapheme_boundary(text, self.anchor)
273+ } else {
274+ self.anchor
275+ };
269276
270− if block_cursor && anchor <= char_idx {
271− Range::new(anchor, next_grapheme_boundary(text, char_idx))
277+ if anchor <= char_idx {
278+ Range::new(anchor, next_grapheme_boundary(text, char_idx))
279+ } else {
280+ Range::new(anchor, char_idx)
281+ }
272282 } else {
273− Range::new(anchor, char_idx)
283+ Range::point(char_idx)
274284 }
275285 }
276286
@@ -309,18 +319,6 @@ impl Selection {
309319 self.ranges[self.primary_index]
310320 }
311321
312− #[must_use]
313− pub fn cursor(&self, text: RopeSlice) -> usize {
314− let range = self.primary();
315−
316− // For 1-width cursor semantics.
317− if range.anchor < range.head {
318− prev_grapheme_boundary(text, range.head).max(range.anchor)
319− } else {
320− range.head
321− }
322− }
323−
324322 /// Ensure selection containing only the primary selection.
325323 pub fn into_single(self) -> Self {
326324 if self.ranges.len() == 1 {
@@ -452,17 +450,9 @@ impl Selection {
452450 }
453451
454452 /// Transforms the selection into all of the left-side head positions,
455− /// using 1-width semantics.
453+ /// using block-cursor semantics.
456454 pub fn cursors(self, text: RopeSlice) -> Self {
457− self.transform(|range| {
458− // For 1-width cursor semantics.
459− let pos = if range.anchor < range.head {
460− prev_grapheme_boundary(text, range.head).max(range.anchor)
461− } else {
462− range.head
463− };
464− Range::new(pos, pos)
465− })
455+ self.transform(|range| Range::point(range.cursor(text)))
466456 }
467457
468458 pub fn fragments<'a>(&'a self, text: RopeSlice<'a>) -> impl Iterator<Item = Cow<str>> + 'a {
helix-core/src/textobject.rs+5−10
@@ -59,17 +59,12 @@ pub fn textobject_word(
5959 textobject: TextObject,
6060 _count: usize,
6161) -> Range {
62− // For 1-width cursor semantics.
63− let head = if range.head > range.anchor {
64− prev_grapheme_boundary(slice, range.head)
65− } else {
66− range.head
67− };
62+ let pos = range.cursor(slice);
6863
69− let word_start = find_word_boundary(slice, head, Direction::Backward);
70− let word_end = match slice.get_char(head).map(categorize_char) {
71− None | Some(CharCategory::Whitespace | CharCategory::Eol) => head,
72− _ => find_word_boundary(slice, head + 1, Direction::Forward),
64+ let word_start = find_word_boundary(slice, pos, Direction::Backward);
65+ let word_end = match slice.get_char(pos).map(categorize_char) {
66+ None | Some(CharCategory::Whitespace | CharCategory::Eol) => pos,
67+ _ => find_word_boundary(slice, pos + 1, Direction::Forward),
7368 };
7469
7570 // Special case.
helix-term/src/commands.rs+65−59
@@ -121,7 +121,10 @@ enum Align {
121121}
122122
123123fn align_view(doc: &Document, view: &mut View, align: Align) {
124− let pos = doc.selection(view.id).cursor(doc.text().slice(..));
124+ let pos = doc
125+ .selection(view.id)
126+ .primary()
127+ .cursor(doc.text().slice(..));
125128 let line = doc.text().char_to_line(pos);
126129
127130 let relative = match align {
@@ -372,17 +375,13 @@ fn goto_line_end(cx: &mut Context) {
372375 let text = doc.text().slice(..);
373376
374377 let selection = doc.selection(view.id).clone().transform(|range| {
375− let line = range.head_line(text);
378+ let line = range.cursor_line(text);
376379 let line_start = text.line_to_char(line);
377380
378381 let pos = graphemes::prev_grapheme_boundary(text, line_end_char_index(&text, line))
379382 .max(line_start);
380383
381− if doc.mode == Mode::Select {
382− range.move_head(text, pos, true)
383− } else {
384− Range::point(pos)
385− }
384+ range.put_cursor(text, pos, doc.mode == Mode::Select)
386385 });
387386 doc.set_selection(view.id, selection);
388387}
@@ -392,14 +391,10 @@ fn goto_line_end_newline(cx: &mut Context) {
392391 let text = doc.text().slice(..);
393392
394393 let selection = doc.selection(view.id).clone().transform(|range| {
395− let line = range.head_line(text);
394+ let line = range.cursor_line(text);
396395 let pos = line_end_char_index(&text, line);
397396
398− if doc.mode == Mode::Select {
399− range.move_head(text, pos, true)
400− } else {
401− Range::point(pos)
402− }
397+ range.put_cursor(text, pos, doc.mode == Mode::Select)
403398 });
404399 doc.set_selection(view.id, selection);
405400}
@@ -409,15 +404,11 @@ fn goto_line_start(cx: &mut Context) {
409404 let text = doc.text().slice(..);
410405
411406 let selection = doc.selection(view.id).clone().transform(|range| {
412− let line = range.head_line(text);
407+ let line = range.cursor_line(text);
413408
414409 // adjust to start of the line
415410 let pos = text.line_to_char(line);
416− if doc.mode == Mode::Select {
417− range.move_head(text, pos, true)
418− } else {
419− Range::point(pos)
420− }
411+ range.put_cursor(text, pos, doc.mode == Mode::Select)
421412 });
422413 doc.set_selection(view.id, selection);
423414}
@@ -427,15 +418,11 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
427418 let text = doc.text().slice(..);
428419
429420 let selection = doc.selection(view.id).clone().transform(|range| {
430− let line = range.head_line(text);
421+ let line = range.cursor_line(text);
431422
432423 if let Some(pos) = find_first_non_whitespace_char(text.line(line)) {
433424 let pos = pos + text.line_to_char(line);
434− if doc.mode == Mode::Select {
435− range.move_head(text, pos, true)
436− } else {
437− Range::point(pos)
438− }
425+ range.put_cursor(text, pos, doc.mode == Mode::Select)
439426 } else {
440427 range
441428 }
@@ -579,8 +566,8 @@ fn extend_next_word_start(cx: &mut Context) {
579566 .min_width_1(text)
580567 .transform(|range| {
581568 let word = movement::move_next_word_start(text, range, count);
582− let pos = graphemes::prev_grapheme_boundary(text, word.head);
583− range.move_head(text, pos, true)
569+ let pos = word.cursor(text);
570+ range.put_cursor(text, pos, true)
584571 });
585572 doc.set_selection(view.id, selection);
586573}
@@ -596,8 +583,8 @@ fn extend_prev_word_start(cx: &mut Context) {
596583 .min_width_1(text)
597584 .transform(|range| {
598585 let word = movement::move_prev_word_start(text, range, count);
599− let pos = word.head;
600− range.move_head(text, pos, true)
586+ let pos = word.cursor(text);
587+ range.put_cursor(text, pos, true)
601588 });
602589 doc.set_selection(view.id, selection);
603590}
@@ -613,8 +600,8 @@ fn extend_next_word_end(cx: &mut Context) {
613600 .min_width_1(text)
614601 .transform(|range| {
615602 let word = movement::move_next_word_end(text, range, count);
616− let pos = graphemes::prev_grapheme_boundary(text, word.head);
617− range.move_head(text, pos, true)
603+ let pos = word.cursor(text);
604+ range.put_cursor(text, pos, true)
618605 });
619606 doc.set_selection(view.id, selection);
620607}
@@ -663,18 +650,13 @@ where
663650
664651 let selection = doc.selection(view.id).clone().transform(|range| {
665652 let range = if range.anchor < range.head {
666− // For 1-width cursor semantics.
653+ // For block-cursor semantics.
667654 Range::new(range.anchor, range.head - 1)
668655 } else {
669656 range
670657 };
671− search_fn(text, ch, range.head, count, inclusive).map_or(range, |pos| {
672− if extend {
673− range.move_head(text, pos, true)
674− } else {
675− Range::point(pos)
676− }
677− })
658+ search_fn(text, ch, range.head, count, inclusive)
659+ .map_or(range, |pos| range.put_cursor(text, pos, extend))
678660 });
679661 doc.set_selection(view.id, selection);
680662 })
@@ -895,7 +877,9 @@ fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
895877 let (view, doc) = current!(cx.editor);
896878 let cursor = coords_at_pos(
897879 doc.text().slice(..),
898− doc.selection(view.id).cursor(doc.text().slice(..)),
880+ doc.selection(view.id)
881+ .primary()
882+ .cursor(doc.text().slice(..)),
899883 );
900884 let doc_last_line = doc.text().len_lines() - 1;
901885
@@ -1220,12 +1204,7 @@ fn collapse_selection(cx: &mut Context) {
12201204 let text = doc.text().slice(..);
12211205
12221206 let selection = doc.selection(view.id).clone().transform(|range| {
1223− let pos = if range.head > range.anchor {
1224− // For 1-width cursor semantics.
1225− graphemes::prev_grapheme_boundary(text, range.head)
1226− } else {
1227− range.head
1228− };
1207+ let pos = range.cursor(text);
12291208 Range::new(pos, pos)
12301209 });
12311210 doc.set_selection(view.id, selection);
@@ -2203,7 +2182,7 @@ fn append_to_line(cx: &mut Context) {
22032182
22042183 let selection = doc.selection(view.id).clone().transform(|range| {
22052184 let text = doc.text().slice(..);
2206− let line = range.head_line(text);
2185+ let line = range.cursor_line(text);
22072186 let pos = line_end_char_index(&text, line);
22082187 Range::new(pos, pos)
22092188 });
@@ -2264,7 +2243,7 @@ fn open(cx: &mut Context, open: Open) {
22642243 let mut offs = 0;
22652244
22662245 let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
2267− let line = range.head_line(text);
2246+ let line = range.cursor_line(text);
22682247
22692248 let line = match open {
22702249 // adjust position to the end of the line (next line - 1)
@@ -2472,7 +2451,9 @@ fn goto_definition(cx: &mut Context) {
24722451
24732452 let pos = pos_to_lsp_pos(
24742453 doc.text(),
2475− doc.selection(view.id).cursor(doc.text().slice(..)),
2454+ doc.selection(view.id)
2455+ .primary()
2456+ .cursor(doc.text().slice(..)),
24762457 offset_encoding,
24772458 );
24782459
@@ -2513,7 +2494,9 @@ fn goto_type_definition(cx: &mut Context) {
25132494
25142495 let pos = pos_to_lsp_pos(
25152496 doc.text(),
2516− doc.selection(view.id).cursor(doc.text().slice(..)),
2497+ doc.selection(view.id)
2498+ .primary()
2499+ .cursor(doc.text().slice(..)),
25172500 offset_encoding,
25182501 );
25192502
@@ -2554,7 +2537,9 @@ fn goto_implementation(cx: &mut Context) {
25542537
25552538 let pos = pos_to_lsp_pos(
25562539 doc.text(),
2557− doc.selection(view.id).cursor(doc.text().slice(..)),
2540+ doc.selection(view.id)
2541+ .primary()
2542+ .cursor(doc.text().slice(..)),
25582543 offset_encoding,
25592544 );
25602545
@@ -2595,7 +2580,9 @@ fn goto_reference(cx: &mut Context) {
25952580
25962581 let pos = pos_to_lsp_pos(
25972582 doc.text(),
2598− doc.selection(view.id).cursor(doc.text().slice(..)),
2583+ doc.selection(view.id)
2584+ .primary()
2585+ .cursor(doc.text().slice(..)),
25992586 offset_encoding,
26002587 );
26012588
@@ -2656,7 +2643,10 @@ fn goto_next_diag(cx: &mut Context) {
26562643 let editor = &mut cx.editor;
26572644 let (view, doc) = current!(editor);
26582645
2659− let cursor_pos = doc.selection(view.id).cursor(doc.text().slice(..));
2646+ let cursor_pos = doc
2647+ .selection(view.id)
2648+ .primary()
2649+ .cursor(doc.text().slice(..));
26602650 let diag = if let Some(diag) = doc
26612651 .diagnostics()
26622652 .iter()
@@ -2677,7 +2667,10 @@ fn goto_prev_diag(cx: &mut Context) {
26772667 let editor = &mut cx.editor;
26782668 let (view, doc) = current!(editor);
26792669
2680− let cursor_pos = doc.selection(view.id).cursor(doc.text().slice(..));
2670+ let cursor_pos = doc
2671+ .selection(view.id)
2672+ .primary()
2673+ .cursor(doc.text().slice(..));
26812674 let diag = if let Some(diag) = doc
26822675 .diagnostics()
26832676 .iter()
@@ -2705,7 +2698,9 @@ fn signature_help(cx: &mut Context) {
27052698
27062699 let pos = pos_to_lsp_pos(
27072700 doc.text(),
2708− doc.selection(view.id).cursor(doc.text().slice(..)),
2701+ doc.selection(view.id)
2702+ .primary()
2703+ .cursor(doc.text().slice(..)),
27092704 language_server.offset_encoding(),
27102705 );
27112706
@@ -3457,7 +3452,10 @@ fn completion(cx: &mut Context) {
34573452 };
34583453
34593454 let offset_encoding = language_server.offset_encoding();
3460− let cursor = doc.selection(view.id).cursor(doc.text().slice(..));
3455+ let cursor = doc
3456+ .selection(view.id)
3457+ .primary()
3458+ .cursor(doc.text().slice(..));
34613459
34623460 let pos = pos_to_lsp_pos(doc.text(), cursor, offset_encoding);
34633461
@@ -3514,7 +3512,9 @@ fn hover(cx: &mut Context) {
35143512
35153513 let pos = pos_to_lsp_pos(
35163514 doc.text(),
3517− doc.selection(view.id).cursor(doc.text().slice(..)),
3515+ doc.selection(view.id)
3516+ .primary()
3517+ .cursor(doc.text().slice(..)),
35183518 language_server.offset_encoding(),
35193519 );
35203520
@@ -3580,7 +3580,10 @@ fn match_brackets(cx: &mut Context) {
35803580 let (view, doc) = current!(cx.editor);
35813581
35823582 if let Some(syntax) = doc.syntax() {
3583− let pos = doc.selection(view.id).cursor(doc.text().slice(..));
3583+ let pos = doc
3584+ .selection(view.id)
3585+ .primary()
3586+ .cursor(doc.text().slice(..));
35843587 if let Some(pos) = match_brackets::find(syntax, doc.text(), pos) {
35853588 let selection = Selection::point(pos);
35863589 doc.set_selection(view.id, selection);
@@ -3684,7 +3687,10 @@ fn align_view_bottom(cx: &mut Context) {
36843687
36853688fn align_view_middle(cx: &mut Context) {
36863689 let (view, doc) = current!(cx.editor);
3687− let pos = doc.selection(view.id).cursor(doc.text().slice(..));
3690+ let pos = doc
3691+ .selection(view.id)
3692+ .primary()
3693+ .cursor(doc.text().slice(..));
36883694 let pos = coords_at_pos(doc.text().slice(..), pos);
36893695
36903696 const OFFSET: usize = 7; // gutters
helix-term/src/ui/completion.rs+16−4
@@ -86,7 +86,10 @@ impl Completion {
8686 let item = item.unwrap();
8787
8888 // if more text was entered, remove it
89− let cursor = doc.selection(view.id).cursor(doc.text().slice(..));
89+ let cursor = doc
90+ .selection(view.id)
91+ .primary()
92+ .cursor(doc.text().slice(..));
9093 if trigger_offset < cursor {
9194 let remove = Transaction::change(
9295 doc.text(),
@@ -109,7 +112,10 @@ impl Completion {
109112 )
110113 } else {
111114 let text = item.insert_text.as_ref().unwrap_or(&item.label);
112− let cursor = doc.selection(view.id).cursor(doc.text().slice(..));
115+ let cursor = doc
116+ .selection(view.id)
117+ .primary()
118+ .cursor(doc.text().slice(..));
113119 Transaction::change(
114120 doc.text(),
115121 vec![(cursor, cursor, Some(text.as_str().into()))].into_iter(),
@@ -155,7 +161,10 @@ impl Completion {
155161 // TODO: hooks should get processed immediately so maybe do it after select!(), before
156162 // looping?
157163
158− let cursor = doc.selection(view.id).cursor(doc.text().slice(..));
164+ let cursor = doc
165+ .selection(view.id)
166+ .primary()
167+ .cursor(doc.text().slice(..));
159168 if self.trigger_offset <= cursor {
160169 let fragment = doc.text().slice(self.trigger_offset..cursor);
161170 let text = Cow::from(fragment);
@@ -212,7 +221,10 @@ impl Component for Completion {
212221 .language()
213222 .and_then(|scope| scope.strip_prefix("source."))
214223 .unwrap_or("");
215− let cursor_pos = doc.selection(view.id).cursor(doc.text().slice(..));
224+ let cursor_pos = doc
225+ .selection(view.id)
226+ .primary()
227+ .cursor(doc.text().slice(..));
216228 let cursor_pos = (helix_core::coords_at_pos(doc.text().slice(..), cursor_pos).row
217229 - view.first_line) as u16;
218230
helix-term/src/ui/editor.rs+11−3
@@ -406,7 +406,10 @@ impl EditorView {
406406 // TODO: set cursor position for IME
407407 if let Some(syntax) = doc.syntax() {
408408 use helix_core::match_brackets;
409− let pos = doc.selection(view.id).cursor(doc.text().slice(..));
409+ let pos = doc
410+ .selection(view.id)
411+ .primary()
412+ .cursor(doc.text().slice(..));
410413 let pos = match_brackets::find(syntax, doc.text(), pos)
411414 .and_then(|pos| view.screen_coords_at_pos(doc, text, pos));
412415
@@ -451,7 +454,10 @@ impl EditorView {
451454 widgets::{Paragraph, Widget},
452455 };
453456
454− let cursor = doc.selection(view.id).cursor(doc.text().slice(..));
457+ let cursor = doc
458+ .selection(view.id)
459+ .primary()
460+ .cursor(doc.text().slice(..));
455461
456462 let diagnostics = doc.diagnostics().iter().filter(|diagnostic| {
457463 diagnostic.range.start <= cursor && diagnostic.range.end >= cursor
@@ -565,7 +571,9 @@ impl EditorView {
565571 let position_info = {
566572 let pos = coords_at_pos(
567573 doc.text().slice(..),
568− doc.selection(view.id).cursor(doc.text().slice(..)),
574+ doc.selection(view.id)
575+ .primary()
576+ .cursor(doc.text().slice(..)),
569577 );
570578 format!("{}:{}", pos.row + 1, pos.col + 1) // convert to 1-indexing
571579 };
helix-view/src/editor.rs+8−2
@@ -145,7 +145,10 @@ impl Editor {
145145 .entry(view.id)
146146 .or_insert_with(|| Selection::point(0));
147147 // TODO: reuse align_view
148− let pos = doc.selection(view.id).cursor(doc.text().slice(..));
148+ let pos = doc
149+ .selection(view.id)
150+ .primary()
151+ .cursor(doc.text().slice(..));
149152 let line = doc.text().char_to_line(pos);
150153 view.first_line = line.saturating_sub(view.area.height as usize / 2);
151154
@@ -295,7 +298,10 @@ impl Editor {
295298 const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
296299 let view = view!(self);
297300 let doc = &self.documents[view.doc];
298− let cursor = doc.selection(view.id).cursor(doc.text().slice(..));
301+ let cursor = doc
302+ .selection(view.id)
303+ .primary()
304+ .cursor(doc.text().slice(..));
299305 if let Some(mut pos) = view.screen_coords_at_pos(doc, doc.text().slice(..), cursor) {
300306 pos.col += view.area.x as usize + OFFSET as usize;
301307 pos.row += view.area.y as usize;
helix-view/src/view.rs+4−1
@@ -84,7 +84,10 @@ impl View {
8484 }
8585
8686 pub fn ensure_cursor_in_view(&mut self, doc: &Document) {
87− let cursor = doc.selection(self.id).cursor(doc.text().slice(..));
87+ let cursor = doc
88+ .selection(self.id)
89+ .primary()
90+ .cursor(doc.text().slice(..));
8891 let pos = coords_at_pos(doc.text().slice(..), cursor);
8992 let line = pos.row;
9093 let col = pos.col;