зеркало из
https://github.com/glebtv/tui-textarea.git
synced 2026-08-28 11:36:17 +03:00
move cursor between paragraphs forward/back
Этот коммит содержится в:
2
.github/workflows/ci.yml
поставляемый
2
.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
|
||||
|
||||
@@ -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])))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ pub enum Key {
|
||||
Delete,
|
||||
Home,
|
||||
End,
|
||||
PageUp,
|
||||
PageDown,
|
||||
Null,
|
||||
}
|
||||
|
||||
@@ -62,6 +64,8 @@ impl From<KeyEvent> 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 }
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![allow(clippy::needless_range_loop)]
|
||||
|
||||
mod cursor;
|
||||
mod history;
|
||||
mod input;
|
||||
|
||||
@@ -37,12 +37,12 @@ impl<'a> Default for TextArea<'a> {
|
||||
}
|
||||
|
||||
impl<'a> TextArea<'a> {
|
||||
pub fn new(mut v: Vec<String>) -> Self {
|
||||
if v.is_empty() {
|
||||
v.push(String::new());
|
||||
pub fn new(mut lines: Vec<String>) -> 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,
|
||||
|
||||
Ссылка в новой задаче
Block a user