on master help sign in
Fixing Multiple Panics (#121)

* init * wip * wip

commitc17dcb8633550a4efde56ca5b4e2b00fbf9f45e1 authorKirawi <67773714+kirawi@users.noreply.github.com> dateFri 4 Jun 2021, 23:49 (5 years ago) parent5a344a3
7 files changed+31−8
helix-core/src/movement.rs+4−1 helix-core/src/selection.rs+1−1 helix-core/src/transaction.rs+19−1 helix-term/src/commands.rs+4−2 helix-term/src/ui/editor.rs+1−1 helix-term/src/ui/prompt.rs+1−1 helix-view/src/view.rs+1−1
helix-core/src/movement.rs+4−1
@@ -45,7 +45,10 @@ pub fn move_vertically(
4545
4646 let new_line = match dir {
4747 Direction::Backward => row.saturating_sub(count),
48− Direction::Forward => std::cmp::min(row.saturating_add(count), text.len_lines() - 2),
48+ Direction::Forward => std::cmp::min(
49+ row.saturating_add(count),
50+ text.len_lines().saturating_sub(2),
51+ ),
4952 };
5053
5154 // convert to 0-indexed, subtract another 1 because len_chars() counts \n
helix-core/src/selection.rs+1−1
@@ -383,7 +383,7 @@ pub fn split_on_matches(
383383 // TODO: retain range direction
384384
385385 let end = text.byte_to_char(start_byte + mat.start());
386− result.push(Range::new(start, end - 1));
386+ result.push(Range::new(start, end.saturating_sub(1)));
387387 start = text.byte_to_char(start_byte + mat.end());
388388 }
389389
helix-core/src/transaction.rs+19−1
@@ -90,7 +90,8 @@ impl ChangeSet {
9090 return;
9191 }
9292
93− self.len_after += fragment.len();
93+ // Avoiding std::str::len() to account for UTF-8 characters.
94+ self.len_after += fragment.chars().count();
9495
9596 let new_last = match self.changes.as_mut_slice() {
9697 [.., Insert(prev)] | [.., Insert(prev), Delete(_)] => {
@@ -754,4 +755,21 @@ mod test {
754755 use Operation::*;
755756 assert_eq!(changes.changes, &[Insert("a".into())]);
756757 }
758+
759+ #[test]
760+ fn combine_with_utf8() {
761+ const TEST_CASE: &'static str = "Hello, これはヒレクスエディターです!";
762+
763+ let empty = Rope::from("");
764+ let mut a = ChangeSet::new(&empty);
765+
766+ let mut b = ChangeSet::new(&empty);
767+ b.insert(TEST_CASE.into());
768+
769+ let changes = a.compose(b);
770+
771+ use Operation::*;
772+ assert_eq!(changes.changes, &[Insert(TEST_CASE.into())]);
773+ assert_eq!(changes.len_after, TEST_CASE.chars().count());
774+ }
757775}
helix-term/src/commands.rs+4−2
@@ -669,7 +669,7 @@ fn _search(doc: &mut Document, view: &mut View, contents: &str, regex: &Regex, e
669669 return;
670670 }
671671
672− let head = end - 1;
672+ let head = end;
673673
674674 let selection = if extend {
675675 selection.clone().push(Range::new(start, head))
@@ -749,7 +749,9 @@ pub fn select_line(cx: &mut Context) {
749749
750750 let line = text.char_to_line(pos.head);
751751 let start = text.line_to_char(line);
752− let end = text.line_to_char(line + count).saturating_sub(1);
752+ let end = text
753+ .line_to_char(std::cmp::min(doc.text().len_lines(), line + count))
754+ .saturating_sub(1);
753755
754756 doc.set_selection(view.id, Selection::single(start, end));
755757}
helix-term/src/ui/editor.rs+1−1
@@ -341,7 +341,7 @@ impl EditorView {
341341 let info: Style = theme.get("info");
342342 let hint: Style = theme.get("hint");
343343
344− for (i, line) in (view.first_line..last_line).enumerate() {
344+ for (i, line) in (view.first_line..=last_line).enumerate() {
345345 use helix_core::diagnostic::Severity;
346346 if let Some(diagnostic) = doc.diagnostics.iter().find(|d| d.line == line) {
347347 surface.set_stringn(
helix-term/src/ui/prompt.rs+1−1
@@ -114,7 +114,7 @@ impl Prompt {
114114 let selected_color = theme.get("ui.menu.selected");
115115 // completion
116116
117− let max_col = area.width / BASE_WIDTH;
117+ let max_col = std::cmp::max(1, area.width / BASE_WIDTH);
118118 let height = ((self.completion.len() as u16 + max_col - 1) / max_col);
119119 let completion_area = Rect::new(
120120 area.x,
helix-view/src/view.rs+1−1
@@ -106,7 +106,7 @@ impl View {
106106 /// Calculates the last visible line on screen
107107 #[inline]
108108 pub fn last_line(&self, doc: &Document) -> usize {
109− let height = self.area.height.saturating_sub(1); // - 1 for statusline
109+ let height = self.area.height.saturating_sub(2); // - 2 for statusline
110110 std::cmp::min(
111111 self.first_line + height as usize,
112112 doc.text().len_lines() - 1,