From 042ea6d4208cfe0749131544454309d5f6d091e4 Mon Sep 17 00:00:00 2001 From: mars Date: Fri, 14 Apr 2023 22:15:48 -0400 Subject: [PATCH] Better handling of EOF --- src/actions.rs | 4 ++-- src/buffer.rs | 43 ++++++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/actions.rs b/src/actions.rs index bc6e2f9..bb1c9a2 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -168,11 +168,11 @@ pub fn redo(state: &mut State) { pub fn delete_char_backward(state: &mut State) { state.move_cursor(Direction::Left); - state.buffer.remove(state.cursor); + state.buffer.remove_char(state.cursor); } pub fn delete_char_forward(state: &mut State) { - state.buffer.remove(state.cursor); + state.buffer.remove_char(state.cursor); } pub fn insert_newline(state: &mut State) { diff --git a/src/buffer.rs b/src/buffer.rs index 3ca275c..e9fa751 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -90,11 +90,6 @@ impl Buffer { let mut line_buf = Vec::::with_capacity(text_width); for (row, line) in (0..rows).zip(self.text.lines_at(scroll.line)) { - // only the last line is empty and should be skipped - if line.len_chars() == 0 { - break; - } - let row = row as usize + scroll.line; let is_selected = row == cursor.line; @@ -104,13 +99,19 @@ impl Buffer { linenr_style }; + let linenr = if line.len_chars() > 0 { + format!("{:>width$} ", row, width = linenr_width as usize) + } else { + // only the last line is empty + format!("{:>width$}", "~", width = linenr_width as usize) + }; + let line_style = if is_selected { styles.get_scope("ui.cursorline.primary").clone() } else { Default::default() }; - let linenr = format!("{:width$} ", row, width = linenr_width as usize); linenr_style.print_styled(out, &linenr)?; let lhs = scroll.column; @@ -149,10 +150,12 @@ impl Buffer { Ok(gutter_width) } - pub fn remove(&mut self, cursor: Cursor) { + pub fn remove_char(&mut self, cursor: Cursor) { let index = self.cursor_to_char(cursor); - self.text.remove(index..=index); - self.style_dirty = true; + if index < self.text.len_chars() { + self.text.remove(index..=index); + self.style_dirty = true; + } } pub fn insert_char(&mut self, cursor: Cursor, c: char) { @@ -222,7 +225,13 @@ impl Buffer { } pub fn clamped_cursor(&self, cursor: Cursor) -> Cursor { - let line_end = self.text.line(cursor.line).len_chars().saturating_sub(1); + let line_len = self.text.line(cursor.line).len_chars(); + + let line_end = if cursor.line + 1 == self.text.len_lines() { + line_len + } else { + line_len.saturating_sub(1) + }; Cursor { line: cursor.line, @@ -248,7 +257,7 @@ impl Buffer { } } Direction::Down => { - if cursor.line + 2 < self.text.len_lines() { + if cursor.line + 1 < self.text.len_lines() { cursor.line += 1; } } @@ -259,13 +268,13 @@ impl Buffer { } Direction::Right => { let line = self.text.line(cursor.line); - if cursor.column + 2 > line.len_chars() { - if enable_linewrap && cursor.line + 2 < self.text.len_lines() { - cursor.line += 1; - cursor.column = 0; - } - } else { + if cursor.line + 1 == self.text.len_lines() && cursor.column < line.len_chars() { cursor.column += 1; + } else if cursor.column + 1 < line.len_chars() { + cursor.column += 1 + } else if enable_linewrap && cursor.line + 1 < self.text.len_lines() { + cursor.line += 1; + cursor.column = 0; } } }