aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.rs105
-rw-r--r--src/rope.rs23
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)) => {