1
0
зеркало из https://github.com/glebtv/tui-textarea.git synced 2026-08-28 11:36:17 +03:00

feat: add screen/data cursor maps for wrapped movement (#17)

* feat!: remove tui-rs support and map screen cursors

* docs(examples): add fixed-size recording mode

* chore(release): bump to v0.11.0
Этот коммит содержится в:
srothgan
2026-05-03 08:48:05 +02:00
коммит произвёл GitHub
родитель f20df6b965
Коммит 8f708cfdc7
28 изменённых файлов: 782 добавлений и 925 удалений

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

@@ -4,6 +4,10 @@ use ratatui::style::{Color, Style};
use ratatui::widgets::Widget as _;
use tui_textarea::{CursorMove, TextArea, WrapMode};
fn cell_symbol(cell: &ratatui::buffer::Cell) -> &str {
cell.symbol()
}
fn render_lines(textarea: &TextArea<'_>, width: u16, height: u16) -> Vec<String> {
let area = Rect {
x: 0,
@@ -18,7 +22,7 @@ fn render_lines(textarea: &TextArea<'_>, width: u16, height: u16) -> Vec<String>
.map(|y| {
let mut line = String::new();
for x in 0..width {
line.push_str(buf[(x, y)].symbol());
line.push_str(cell_symbol(&buf[(x, y)]));
}
line
})
@@ -409,6 +413,56 @@ fn wrapped_cursor_column_clamped_to_shorter_visual_line() {
assert_eq!(textarea.cursor(), (0, 8));
}
#[test]
fn wrapped_cursor_down_preserves_visual_column_for_mixed_width_same_logical_line() {
let mut textarea = TextArea::from(["a中bcde"]);
textarea.set_wrap_mode(WrapMode::Glyph);
render(&textarea, 4, 4);
// After `a中`, the data column is 2 but the visual column is 3.
textarea.move_cursor(CursorMove::Jump(0, 2));
assert_eq!(textarea.cursor(), (0, 2));
textarea.move_cursor(CursorMove::Down);
assert_eq!(textarea.cursor(), (0, 6));
}
#[test]
fn wrapped_cursor_up_preserves_visual_column_for_mixed_width_same_logical_line() {
let mut textarea = TextArea::from(["a中bcde"]);
textarea.set_wrap_mode(WrapMode::Glyph);
render(&textarea, 4, 4);
textarea.move_cursor(CursorMove::Jump(0, 6));
assert_eq!(textarea.cursor(), (0, 6));
textarea.move_cursor(CursorMove::Up);
assert_eq!(textarea.cursor(), (0, 2));
}
#[test]
fn wrapped_cursor_down_preserves_visual_column_when_crossing_into_mixed_width_line() {
let mut textarea = TextArea::from(["abcd", "a中bcde"]);
textarea.set_wrap_mode(WrapMode::Glyph);
render(&textarea, 4, 4);
// Visual column 3 in ASCII should land at visual column 3 in the mixed-width row.
textarea.move_cursor(CursorMove::Jump(0, 3));
assert_eq!(textarea.cursor(), (0, 3));
textarea.move_cursor(CursorMove::Down);
assert_eq!(textarea.cursor(), (1, 2));
}
#[test]
fn wrapped_cursor_up_preserves_visual_column_when_crossing_out_of_mixed_width_line() {
let mut textarea = TextArea::from(["abcd", "a中bcde"]);
textarea.set_wrap_mode(WrapMode::Glyph);
render(&textarea, 4, 4);
textarea.move_cursor(CursorMove::Jump(1, 2));
assert_eq!(textarea.cursor(), (1, 2));
textarea.move_cursor(CursorMove::Up);
assert_eq!(textarea.cursor(), (0, 3));
}
#[test]
fn wrapped_cursor_down_up_with_word_wrap_mode() {
// "hello world" at width=6 with Word wrap: