diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4affff0..f9c8fb8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,6 @@ jobs: - name: rustfmt run: cargo fmt -- --check - name: clippy - run: cargo clippy -- -D warnings + run: cargo clippy --examples --all-features -- -D warnings - name: clippy with --no-default-features run: cargo clippy --no-default-features -- -D warnings diff --git a/src/cursor.rs b/src/cursor.rs index c87e40f..052598a 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -12,6 +12,8 @@ pub enum CursorMove { Bottom, WordForward, WordBack, + ParagraphForward, + ParagraphBack, } #[derive(PartialEq, Eq, Clone, Copy)] @@ -124,6 +126,31 @@ impl CursorMove { Some((row, 0)) } } + ParagraphForward => { + let mut prev_is_empty = lines[row].is_empty(); + for row in row + 1..lines.len() { + let line = &lines[row]; + let is_empty = line.is_empty(); + if !is_empty && prev_is_empty { + return Some((row, fit_col(col, line))); + } + prev_is_empty = is_empty; + } + let row = lines.len() - 1; + Some((row, fit_col(col, &lines[row]))) + } + ParagraphBack if row == 0 => None, + ParagraphBack => { + let mut prev_is_empty = lines[row - 1].is_empty(); + for row in (0..row - 1).rev() { + let is_empty = lines[row].is_empty(); + if is_empty && !prev_is_empty { + return Some((row + 1, fit_col(col, &lines[row + 1]))); + } + prev_is_empty = is_empty; + } + Some((0, fit_col(col, &lines[0]))) + } } } } diff --git a/src/input.rs b/src/input.rs index bb87f26..0a63459 100644 --- a/src/input.rs +++ b/src/input.rs @@ -14,6 +14,8 @@ pub enum Key { Delete, Home, End, + PageUp, + PageDown, Null, } @@ -62,6 +64,8 @@ impl From for Input { KeyCode::Delete => Key::Delete, KeyCode::Home => Key::Home, KeyCode::End => Key::End, + KeyCode::PageUp => Key::PageUp, + KeyCode::PageDown => Key::PageDown, _ => Key::Null, }; Self { key, ctrl, alt } diff --git a/src/lib.rs b/src/lib.rs index b4bb7a0..289fe4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::needless_range_loop)] + mod cursor; mod history; mod input; diff --git a/src/textarea.rs b/src/textarea.rs index 472f77d..4663552 100644 --- a/src/textarea.rs +++ b/src/textarea.rs @@ -37,12 +37,12 @@ impl<'a> Default for TextArea<'a> { } impl<'a> TextArea<'a> { - pub fn new(mut v: Vec) -> Self { - if v.is_empty() { - v.push(String::new()); + pub fn new(mut lines: Vec) -> Self { + if lines.is_empty() { + lines.push(String::new()); } Self { - lines: v, + lines, block: None, style: Style::default(), cursor: (0, 0), @@ -204,6 +204,22 @@ impl<'a> TextArea<'a> { ctrl: true, alt: false, } => self.move_cursor(CursorMove::WordBack), + Input { + key: Key::Char('n'), + ctrl: false, + alt: true, + } + | Input { + key: Key::PageDown, .. + } => self.move_cursor(CursorMove::ParagraphForward), + Input { + key: Key::Char('p'), + ctrl: false, + alt: true, + } + | Input { + key: Key::PageUp, .. + } => self.move_cursor(CursorMove::ParagraphBack), Input { key: Key::Char('u'), ctrl: true,