diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 63 | ||||
| -rw-r--r-- | src/rope.rs | 17 |
2 files changed, 58 insertions, 22 deletions
diff --git a/src/main.rs b/src/main.rs index 7f2beaa..c9e8928 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,19 +46,51 @@ impl State { return Ok(pos); } + fn repaint_full(&mut self) -> Result<(), Box<dyn Error>> { + let size = term::size()?; + + write!(stdout(), "\x1b[H\x1b[J")?; + for i in 0..usize::from(size.ws_row) { + if i > 0 { + write!(stdout(), "\r\n")?; + } + if i > self.buf.lines() { + break; + } + let line = self.buf.line(i); + let max_len = line.char(usize::from(size.ws_col-1)); + line.slice(0, max_len).print(&mut stdout())?; + if max_len < line.len() { + write!(stdout(), "\x1b[30m\x1b[47m>\x1b[m")?; + } + } + return Ok(()); + } + fn repaint_line_full(&mut self) -> Result<(), Box<dyn Error>> { - write!(stdout(), "\x1b[{}H", self.cursor_row+1)?; - let line = self.buf.line(self.cursor_row); + let term_size = term::size()?; + + write!(stdout(), "\x1b[{}H\x1b[K", self.cursor_row+1)?; + let mut line = self.buf.line(self.cursor_row); + let max_len = line.char(usize::from(term_size.ws_col-1)); + let mut truncated = false; + if max_len < line.len() { + line = line.slice(0, max_len); + truncated = true; + } line.print(&mut stdout())?; let (_, col) = self.cursor_pos()?; self.line_cols = col; if self.cursor_col >= self.line_cols { self.line_offset = line.len(); + if truncated { + write!(stdout(), "\x1b[30m\x1b[47m>\x1b[m\x1b[{}G", self.cursor_col+1)?; + } return Ok(()); } - let mut lo = line.ceil_char_boundary(self.cursor_col); + let mut lo = line.char(self.cursor_col); let mut hi = line.len(); // Binary search :D while hi > lo { @@ -73,8 +105,11 @@ impl State { } } self.line_offset = line.floor_char_boundary(lo-1); - write!(stdout(), "\x1b[G\x1b[K")?; + write!(stdout(), "\x1b[G")?; line.print(&mut stdout())?; + if truncated { + write!(stdout(), "\x1b[30m\x1b[47m>\x1b[m")?; + } write!(stdout(), "\x1b[{}G", self.cursor_col+1)?; return Ok(()); } @@ -92,22 +127,7 @@ fn edit(file: &OsStr) -> Result<(), Box<dyn Error>> { line_offset: 0, line_cols: 0, }; - let _ = write!(stdout(), "\x1b[J"); - for i in 0..usize::from(size.ws_row) { - if i > 0 { - let _ = write!(stdout(), "\r\n"); - } - if i > state.buf.lines() { - break; - } - let line = state.buf.line(i); - // TODO: handle line-wrapping. - let _ = line.print(&mut stdout()); - if i == 0 { - let (_, col) = state.cursor_pos()?; - state.line_cols = col; - } - } + let _ = state.repaint_full(); let _ = write!(stdout(), "\x1b[H"); let _ = stdout().flush(); @@ -144,8 +164,7 @@ fn edit(file: &OsStr) -> Result<(), Box<dyn Error>> { state.cursor_row -= 1; let _ = state.repaint_line_full(); state.cursor_col = state.line_cols; - state.line_offset = state.buf.line(state.cursor_row).len(); - let _ = write!(stdout(), "\x1b[{}G", state.cursor_col+1); + let _ = state.repaint_line_full(); } else { state.cursor_col -= 1; let _ = state.repaint_line_full(); diff --git a/src/rope.rs b/src/rope.rs index c5e9aa1..5f4fca8 100644 --- a/src/rope.rs +++ b/src/rope.rs @@ -278,4 +278,21 @@ impl Rope { } return self.len(); } + + pub fn char(&self, index: usize) -> usize { + if index == 0 { + return 0; + } + let mut count = 1; + for i in 1..self.len() { + if !self.is_char_boundary(i) { + continue; + } + if count == index { + return i; + } + count += 1; + } + return self.len(); + } } |
