aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Vegdahl2021-07-22 18:17:03 +0000
committerNathan Vegdahl2021-07-22 18:17:03 +0000
commit5841954f58702ba2eabc17d96f0bf167cb13af24 (patch)
treef9fc4febfe658b36ee7a03790480d2bdd8722f56
parent673338bdb6064ff98e8822a251fd31664909610d (diff)
Calculate the line that the range head is on correctly.
-rw-r--r--helix-core/src/selection.rs12
-rw-r--r--helix-term/src/commands.rs35
2 files changed, 24 insertions, 23 deletions
diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs
index 3d4ee768..6ca52ebf 100644
--- a/helix-core/src/selection.rs
+++ b/helix-core/src/selection.rs
@@ -73,6 +73,18 @@ impl Range {
std::cmp::max(self.anchor, self.head)
}
+ /// The line number that the head is on (using 1-width semantics).
+ #[inline]
+ #[must_use]
+ pub fn head_line(&self, text: RopeSlice) -> usize {
+ let head = if self.anchor < self.head {
+ prev_grapheme_boundary(text, self.head)
+ } else {
+ self.head
+ };
+ text.char_to_line(head)
+ }
+
/// The (inclusive) range of lines that the range overlaps.
#[inline]
#[must_use]
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index a17245aa..c6f592d9 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -396,19 +396,14 @@ fn goto_line_end(cx: &mut Context) {
view.id,
doc.selection(view.id).clone().transform(|range| {
let text = doc.text().slice(..);
-
- 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 line = range.head_line(text);
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));
+
+ pos = range.head.max(pos).max(text.line_to_char(line));
range.put(text, pos, doc.mode == Mode::Select)
}),
@@ -422,13 +417,7 @@ fn goto_line_end_newline(cx: &mut Context) {
view.id,
doc.selection(view.id).clone().transform(|range| {
let text = doc.text().slice(..);
-
- 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 line = range.head_line(text);
let mut pos = text.line_to_char((line + 1).min(text.len_lines()));
if doc.mode != Mode::Select {
@@ -445,7 +434,7 @@ fn goto_line_start(cx: &mut Context) {
view.id,
doc.selection(view.id).clone().transform(|range| {
let text = doc.text().slice(..);
- let line = text.char_to_line(range.head);
+ let line = range.head_line(text);
// adjust to start of the line
let pos = text.line_to_char(line);
@@ -460,10 +449,10 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
view.id,
doc.selection(view.id).clone().transform(|range| {
let text = doc.text().slice(..);
- let line_idx = text.char_to_line(range.head);
+ let line = range.head_line(text);
- if let Some(pos) = find_first_non_whitespace_char(text.line(line_idx)) {
- let pos = pos + text.line_to_char(line_idx);
+ if let Some(pos) = find_first_non_whitespace_char(text.line(line)) {
+ let pos = pos + text.line_to_char(line);
range.put(text, pos, doc.mode == Mode::Select)
} else {
range
@@ -2212,9 +2201,9 @@ fn append_to_line(cx: &mut Context) {
doc.set_selection(
view.id,
doc.selection(view.id).clone().transform(|range| {
- let text = &doc.text().slice(..);
- let line = text.char_to_line(range.head);
- let pos = line_end_char_index(text, line);
+ let text = doc.text().slice(..);
+ let line = range.head_line(text);
+ let pos = line_end_char_index(&text, line);
Range::new(pos, pos)
}),
);
@@ -2274,7 +2263,7 @@ fn open(cx: &mut Context, open: Open) {
let mut offs = 0;
let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
- let line = text.char_to_line(range.head);
+ let line = range.head_line(text);
let line = match open {
// adjust position to the end of the line (next line - 1)