diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 24 | ||||
| -rw-r--r-- | src/rope.rs | 25 |
2 files changed, 36 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs index 0cc9ad4..3663052 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ fn line_offset(stdin: &mut Reader, line: &Rope, col: u16) -> Result<usize, Box<d return Ok(i); } let c = line.byte(i); - if c > 127 { + if !(c == b'\t' || b' ' <= c && c <= b'~') { break; } if n == col { @@ -231,12 +231,12 @@ impl State { } fn keypress(&mut self, key: Key) -> Result<bool, Box<dyn Error>> { - const CTRL_Q: char = (b'Q' - b'@') as char; - const CTRL_S: char = (b'S' - b'@') as char; - const CTRL_Y: char = (b'Y' - b'@') as char; - const CTRL_Z: char = (b'Z' - b'@') as char; - const BACKSPACE: char = (b'H' - b'@') as char; - const OTHER_BACKSPACE: char = '\x7f'; + const CTRL_Q: char = (b'Q' ^ b'@') as char; + const CTRL_S: char = (b'S' ^ b'@') as char; + const CTRL_Y: char = (b'Y' ^ b'@') as char; + const CTRL_Z: char = (b'Z' ^ b'@') as char; + const BACKSPACE: char = (b'H' ^ b'@') as char; + const OTHER_BACKSPACE: char = (b'?' ^ b'@') as char; let inserting = self.inserting; self.inserting = false; @@ -448,7 +448,7 @@ impl State { } Key::Char(CTRL_S) => { let mut f = File::create(&self.path)?; - self.buf.print(&mut f)?; + self.buf.write(&mut f)?; f.sync_all()?; } Key::Char(CTRL_Z) => { @@ -546,15 +546,15 @@ impl State { .line_start(self.row_start + usize::from(self.cursor_row)) + self.line_offset; let mut buf = [0; 4]; - let s = c.encode_utf8(&mut buf); + let r = Rope::new(c.encode_utf8(&mut buf)); self.buf = self .buf .slice(0, offset) - .concat(&Rope::new(s)) + .concat(&r) .concat(&self.buf.slice(offset, self.buf.len())); - self.line_offset += s.len(); + self.line_offset += r.len(); self.need_repaint_line = true; - stdout().write_all(s.as_bytes())?; + r.print(&mut stdout())?; stdout().flush()?; } } diff --git a/src/rope.rs b/src/rope.rs index ab9a7bc..ec25f61 100644 --- a/src/rope.rs +++ b/src/rope.rs @@ -342,7 +342,16 @@ impl Rope { pub fn print(&self, w: &mut dyn Write) -> Result<(), std::io::Error> { match self { Rope(Node::Leaf(l)) => { - w.write_all(l.buf().as_bytes())?; + for c in l.buf().chars() { + if c < ' ' || c == '\x7f' { + let b = u8::try_from(c).expect("c should be less than \\x7f"); + write!(w, "\x1b[36m^{}\x1b[m", char::from(b ^ 0x40))?; + } else if '\u{80}' <= c && c <= '\u{9f}' { + write!(w, "\x1b[36m<{:x}>\x1b[m", u32::from(c))?; + } else { + write!(w, "{}", c)?; + } + } Ok(()) } Rope(Node::Branch(b)) => { @@ -354,6 +363,20 @@ impl Rope { } } + pub fn write(&self, w: &mut dyn Write) -> Result<(), std::io::Error> { + match self { + Rope(Node::Leaf(l)) => { + w.write_all(l.buf().as_bytes())?; + } + Rope(Node::Branch(b)) => { + for c in b.children.iter() { + c.write(w)?; + } + } + } + Ok(()) + } + pub fn slice(&self, start: usize, end: usize) -> Rope { if start > self.len() { panic!( |
