diff options
| -rw-r--r-- | src/main.rs | 105 | ||||
| -rw-r--r-- | src/rope.rs | 23 |
2 files changed, 91 insertions, 37 deletions
diff --git a/src/main.rs b/src/main.rs index 4c93cb7..3745553 100644 --- a/src/main.rs +++ b/src/main.rs @@ -114,6 +114,64 @@ impl State { write!(stdout(), "\x1b[{}G", self.cursor_col+1)?; return Ok(()); } + + fn up(&mut self) -> Result<(), Box<dyn Error>> { + if self.cursor_row == 0 && self.row_start == 0 { + return Ok(()); + } + if self.cursor_row == 0 { + self.row_start -= 1; + self.repaint_all()?; + } else { + self.cursor_row -= 1; + } + return Ok(()); + } + + fn down(&mut self) -> Result<(), Box<dyn Error>> { + if self.row_start+self.cursor_row == self.buf.lines() { + return Ok(()); + } + let size = term::size()?; + if self.cursor_row == usize::from(size.ws_row - 1) { + self.row_start += 1; + self.repaint_all()?; + } else { + self.cursor_row += 1; + } + return Ok(()); + } + + fn left(&mut self) -> Result<(), Box<dyn Error>> { + if self.cursor_col > self.line_cols { + self.cursor_col = self.line_cols; + } + if self.cursor_col == 0 && self.cursor_row == 0 { + return Ok(()); + } + if self.cursor_col == 0 { + self.up()?; + self.repaint_line_full()?; + self.cursor_col = self.line_cols; + } else { + self.cursor_col -= 1; + } + return Ok(()); + } + + fn right(&mut self) -> Result<(), Box<dyn Error>> { + let size = term::size()?; + if self.cursor_col >= self.line_cols && self.cursor_row == usize::from(size.ws_row-1) { + return Ok(()); + } + if self.cursor_col >= self.line_cols { + self.down()?; + self.cursor_col = 0; + } else { + self.cursor_col += 1; + } + return Ok(()); + } } fn edit(file: &OsStr) -> Result<(), Box<dyn Error>> { @@ -143,51 +201,34 @@ fn edit(file: &OsStr) -> Result<(), Box<dyn Error>> { let _ = state.buf.save(Path::new(file)); } Key::Up => { - if state.cursor_row == 0 && state.row_start == 0 { - continue; - } - if state.cursor_row == 0 { - state.row_start -= 1; - let _ = state.repaint_all(); - } else { - state.cursor_row -= 1; - } + let _ = state.up(); let _ = state.repaint_line_full(); let _ = stdout().flush(); } Key::Down => { - if state.row_start+state.cursor_row == state.buf.lines() { - continue; - } - if state.cursor_row == usize::from(size.ws_row - 1) { - state.row_start += 1; - let _ = state.repaint_all(); - } else { - state.cursor_row += 1; - } + let _ = state.down(); let _ = state.repaint_line_full(); let _ = stdout().flush(); } Key::Left => { - state.cursor_col = std::cmp::min(state.cursor_col, state.line_cols); - if state.cursor_col == 0 { - state.cursor_row -= 1; - let _ = state.repaint_line_full(); - state.cursor_col = state.line_cols; - let _ = state.repaint_line_full(); - } else { - state.cursor_col -= 1; - let _ = state.repaint_line_full(); - } + let _ = state.left(); + let _ = state.repaint_line_full(); let _ = stdout().flush(); } Key::Right => { - if state.cursor_col >= state.line_cols { - state.cursor_row += 1; - state.cursor_col = 0; + let _ = state.right(); + let _ = state.repaint_line_full(); + let _ = stdout().flush(); + } + Key::Char(b'\r') => { + state.buf = state.buf.insert(state.buf.line_idx(state.row_start+state.cursor_row)+state.line_offset, b'\n'); + if state.cursor_row == usize::from(size.ws_row - 1) { + state.row_start += 1; } else { - state.cursor_col += 1; + state.cursor_row += 1; } + state.cursor_col = 0; + let _ = state.repaint_all(); let _ = state.repaint_line_full(); let _ = stdout().flush(); } diff --git a/src/rope.rs b/src/rope.rs index 11a030b..5454557 100644 --- a/src/rope.rs +++ b/src/rope.rs @@ -152,11 +152,24 @@ impl Rope { new_buf[pos + 1..].copy_from_slice(&l.bytes()[pos..]); return Rope::leaf(new_buf); } - let mut buf_left = vec![0; pos + 1]; - buf_left[..pos].copy_from_slice(&l.bytes()[..pos]); - buf_left[pos] = c; - let mut buf_right = Vec::new(); - buf_right.extend_from_slice(&l.bytes()[pos..]); + let half = MAX_NODE_SIZE / 2; + let mut buf_left; + let mut buf_right; + if pos <= half { + buf_left = vec![0; half+1]; + buf_right = vec![0; half]; + buf_left[..pos].copy_from_slice(&l.bytes()[..pos]); + buf_left[pos] = c; + buf_left[pos+1..].copy_from_slice(&l.bytes()[pos..half]); + buf_right.copy_from_slice(&l.bytes()[half..]); + } else { + buf_left = vec![0; half]; + buf_right = vec![0; half+1]; + buf_left.copy_from_slice(&l.bytes()[..half]); + buf_right[..pos-half].copy_from_slice(&l.bytes()[half..pos]); + buf_right[pos-half] = c; + buf_right[pos-half+1..].copy_from_slice(&l.bytes()[pos..]); + } return Rope::leaf(buf_left).concat(&Rope::leaf(buf_right)); } Rope(Node::Branch(b)) => { |
