1
0
зеркало из https://github.com/glebtv/tui-textarea.git synced 2026-09-03 14:26:17 +03:00
Этот коммит содержится в:
rhysd
2022-06-09 22:56:43 +09:00
родитель fc9f017db3
Коммит 58b0381ec7
3 изменённых файлов: 74 добавлений и 63 удалений

56
src/cursor.rs Обычный файл
Просмотреть файл

@@ -0,0 +1,56 @@
#[derive(Clone, Copy, Debug)]
pub enum CursorMove {
Forward,
Back,
Up,
Down,
Head,
End,
}
impl CursorMove {
pub fn next_cursor(
&self,
(row, col): (usize, usize),
lines: &[String],
) -> Option<(usize, usize)> {
match self {
CursorMove::Forward if col + 1 >= lines[row].chars().count() => {
if row + 1 < lines.len() {
Some((row + 1, 0))
} else {
None
}
}
CursorMove::Forward => Some((row, col + 1)),
CursorMove::Back if col == 0 => {
if row > 0 {
Some((row - 1, lines[row - 1].chars().count() - 1))
} else {
None
}
}
CursorMove::Back => Some((row, col - 1)),
CursorMove::Up if row == 0 => None,
CursorMove::Up => {
let mut col = col;
let end = lines[row - 1].chars().count();
if end <= col {
col = end - 1;
}
Some((row - 1, col))
}
CursorMove::Down if row + 1 >= lines.len() => None,
CursorMove::Down => {
let mut col = col;
let end = lines[row + 1].chars().count();
if end <= col {
col = end - 1;
}
Some((row + 1, col))
}
CursorMove::Head => Some((row, 0)),
CursorMove::End => Some((row, lines[row].chars().count() - 1)),
}
}
}

Просмотреть файл

@@ -1,7 +1,9 @@
mod cursor;
mod edit;
mod history;
mod input;
mod textarea;
pub use cursor::CursorMove;
pub use input::{Input, Key};
pub use textarea::TextArea;

Просмотреть файл

@@ -1,3 +1,4 @@
use crate::cursor::CursorMove;
use crate::edit::{Edit, EditKind};
use crate::history::EditHistory;
use crate::input::{Input, Key};
@@ -34,12 +35,12 @@ impl<'a> TextArea<'a> {
match input.key {
Key::Char('h') => self.delete_char(),
Key::Char('m') => self.insert_newline(),
Key::Char('p') => self.cursor_up(),
Key::Char('f') => self.cursor_forward(),
Key::Char('n') => self.cursor_down(),
Key::Char('b') => self.cursor_back(),
Key::Char('a') => self.cursor_start(),
Key::Char('e') => self.cursor_end(),
Key::Char('p') => self.move_cursor(CursorMove::Up),
Key::Char('f') => self.move_cursor(CursorMove::Forward),
Key::Char('n') => self.move_cursor(CursorMove::Down),
Key::Char('b') => self.move_cursor(CursorMove::Back),
Key::Char('a') => self.move_cursor(CursorMove::Head),
Key::Char('e') => self.move_cursor(CursorMove::End),
Key::Char('u') => self.undo(),
Key::Char('r') => self.redo(),
_ => {}
@@ -50,12 +51,12 @@ impl<'a> TextArea<'a> {
Key::Backspace => self.delete_char(),
Key::Tab => self.insert_tab(),
Key::Enter => self.insert_newline(),
Key::Up => self.cursor_up(),
Key::Right => self.cursor_forward(),
Key::Down => self.cursor_down(),
Key::Left => self.cursor_back(),
Key::Home => self.cursor_start(),
Key::End => self.cursor_end(),
Key::Up => self.move_cursor(CursorMove::Up),
Key::Right => self.move_cursor(CursorMove::Forward),
Key::Down => self.move_cursor(CursorMove::Down),
Key::Left => self.move_cursor(CursorMove::Back),
Key::Home => self.move_cursor(CursorMove::Head),
Key::End => self.move_cursor(CursorMove::End),
_ => {}
}
}
@@ -165,60 +166,12 @@ impl<'a> TextArea<'a> {
}
}
pub fn cursor_forward(&mut self) {
let (r, c) = self.cursor;
if c + 1 >= self.lines[r].chars().count() {
if r + 1 < self.lines.len() {
self.cursor = (r + 1, 0);
}
} else {
self.cursor.1 += 1;
pub fn move_cursor(&mut self, m: CursorMove) {
if let Some(cursor) = m.next_cursor(self.cursor, &self.lines) {
self.cursor = cursor;
}
}
pub fn cursor_back(&mut self) {
let (r, c) = self.cursor;
if c == 0 {
if r > 0 {
self.cursor = (r - 1, self.lines[r - 1].chars().count() - 1);
}
} else {
self.cursor.1 -= 1;
}
}
pub fn cursor_down(&mut self) {
let (r, c) = self.cursor;
if r + 1 >= self.lines.len() {
return;
}
self.cursor.0 += 1;
let len = self.lines[r + 1].chars().count();
if len <= c {
self.cursor.1 = len - 1;
}
}
pub fn cursor_up(&mut self) {
let (r, c) = self.cursor;
if r == 0 {
return;
}
self.cursor.0 -= 1;
let len = self.lines[r - 1].chars().count();
if len <= c {
self.cursor.1 = len - 1;
}
}
pub fn cursor_start(&mut self) {
self.cursor.1 = 0;
}
pub fn cursor_end(&mut self) {
self.cursor.1 = self.lines[self.cursor.0].chars().count() - 1;
}
pub fn undo(&mut self) {
if let Some(cursor) = self.history.undo(&mut self.lines) {
self.cursor = cursor;