diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/src/main.rs b/src/main.rs index 3745553..54b644d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,20 +49,24 @@ impl State { fn repaint_all(&mut self) -> Result<(), Box<dyn Error>> { let size = term::size()?; + let mut stdout = stdout().lock(); - write!(stdout(), "\x1b[H\x1b[J")?; + write!(stdout, "\x1b[H\x1b[J")?; for i in self.row_start..self.row_start+usize::from(size.ws_row) { if i > 0 { - write!(stdout(), "\r\n")?; + write!(stdout, "\r\n")?; } if i > self.buf.lines() { break; } - let line = self.buf.line(i); + let mut 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")?; + line = line.slice(0, max_len); + } + line.print(&mut stdout)?; + if max_len < line.len() { + write!(stdout, "\x1b[30m\x1b[47m>\x1b[m")?; } } return Ok(()); @@ -70,8 +74,9 @@ impl State { fn repaint_line_full(&mut self) -> Result<(), Box<dyn Error>> { let term_size = term::size()?; + let mut stdout = stdout().lock(); - write!(stdout(), "\x1b[{}H\x1b[K", self.cursor_row+1)?; + write!(stdout, "\x1b[{}H\x1b[K", self.cursor_row+1)?; let mut line = self.buf.line(self.row_start+self.cursor_row); let max_len = line.char(usize::from(term_size.ws_col-1)); let mut truncated = false; @@ -80,24 +85,34 @@ impl State { truncated = true; } - line.print(&mut stdout())?; + 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)?; + write!(stdout, "\x1b[30m\x1b[47m>\x1b[m\x1b[{}G", self.cursor_col+1)?; } return Ok(()); } - let mut lo = line.char(self.cursor_col); + let offset_guess = line.char(self.cursor_col); + write!(stdout, "\x1b[G")?; + line.slice(0, offset_guess).print(&mut stdout)?; + let (_, col) = self.cursor_pos()?; + if col == self.cursor_col { + // One codepoint per column, like God intended. + self.line_offset = offset_guess; + return Ok(()); + } + + let mut lo = offset_guess; let mut hi = line.len(); // Binary search :D while hi > lo { let x = line.floor_char_boundary(lo + (hi - lo) / 2); - write!(stdout(), "\x1b[G")?; - line.slice(0, x).print(&mut stdout())?; + write!(stdout, "\x1b[G")?; + line.slice(0, x).print(&mut stdout)?; let (_, col) = self.cursor_pos()?; if col <= self.cursor_col { lo = line.ceil_char_boundary(x+1); @@ -106,12 +121,12 @@ impl State { } } self.line_offset = line.floor_char_boundary(lo-1); - write!(stdout(), "\x1b[G")?; - line.print(&mut stdout())?; + write!(stdout, "\x1b[G")?; + line.print(&mut stdout)?; if truncated { - write!(stdout(), "\x1b[30m\x1b[47m>\x1b[m")?; + write!(stdout, "\x1b[30m\x1b[47m>\x1b[m")?; } - write!(stdout(), "\x1b[{}G", self.cursor_col+1)?; + write!(stdout, "\x1b[{}G", self.cursor_col+1)?; return Ok(()); } |
