diff options
| -rw-r--r-- | src/main.rs | 19 | ||||
| -rw-r--r-- | src/rope.rs | 19 |
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"); + } + } + } } |
