aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.rs19
-rw-r--r--src/rope.rs19
2 files changed, 38 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
index 2b6a814..0dfe335 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -20,6 +20,25 @@ fn line_offset(
line: &Rope,
col: u16,
) -> Result<usize, Box<dyn Error>> {
+ let mut n = 0;
+ for i in 0.. {
+ if i == line.len() {
+ return Ok(i);
+ }
+ let c = line.byte(i);
+ if c > 127 {
+ break;
+ }
+ if n == col {
+ return Ok(i);
+ }
+ if c == b'\t' {
+ n += 8 - n % 8;
+ } else {
+ n += 1;
+ }
+ }
+
// Binary search :D
let mut lo = 0;
let mut hi = line.len() + 1;
diff --git a/src/rope.rs b/src/rope.rs
index 31c3296..737d949 100644
--- a/src/rope.rs
+++ b/src/rope.rs
@@ -355,4 +355,23 @@ impl Rope {
}
}
}
+
+ pub fn byte(&self, i: usize) -> u8 {
+ if i >= self.len() {
+ panic!("Index {} out of range 0..{}", i, self.len());
+ }
+ match self {
+ Rope(Node::Leaf(l)) => l.bytes()[i],
+ Rope(Node::Branch(b)) => {
+ let mut i = i;
+ for c in b.children().iter() {
+ if i < c.len() {
+ return c.byte(i);
+ }
+ i -= c.len();
+ }
+ panic!("unreachable");
+ }
+ }
+ }
}