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

feat(keymap): bind Ctrl+Backspace/Ctrl+Delete to word deletion

Add the de-facto standard terminal/editor hotkeys to the default key map:
- Ctrl+Backspace -> delete_word
- Ctrl+Delete -> delete_next_word

Previously only Alt+Backspace/Ctrl+w and Alt+Delete/Alt+d were bound,
which conflicts with muscle memory from readline, VS Code and other TUIs.
Этот коммит содержится в:
Gleb Tv
2026-08-17 20:47:38 +03:00
родитель 9b5afba816
Коммит b542e179ae
3 изменённых файлов: 110 добавлений и 1 удалений

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

@@ -1,5 +1,11 @@
# Changelog
## [0.12.2] - 2026-08-17 [Changes][v0.12.2]
### Features
- **Common word-deletion hotkeys**: Bind `Ctrl+Backspace` to [`TextArea::delete_word`] and `Ctrl+Delete` to [`TextArea::delete_next_word`] in the default key map, matching the de-facto terminal/editor convention (readline, VS Code, opencode).
## [0.12.1] - 2026-07-10 [Changes][v0.12.1]
### Features

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

@@ -3,7 +3,7 @@ name = "tui-textarea-2"
homepage = "https://github.com/srothgan/tui-textarea#readme"
repository = "https://github.com/srothgan/tui-textarea"
documentation = "https://docs.rs/tui-textarea-2/latest/tui_textarea/"
version = "0.12.1"
version = "0.12.2"
edition = "2024"
rust-version = "1.88.0" # for Ratatui 0.30 split crates
authors = ["Simon Peter Rothgang <simonrothgang@icloud.com>", "rhysd <lin90162@yahoo.co.jp>"]

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

@@ -480,6 +480,12 @@ impl<'a> TextArea<'a> {
ctrl: false,
alt: true,
..
}
| Input {
key: Key::Backspace,
ctrl: true,
alt: false,
..
} => self.delete_word(),
Input {
key: Key::Delete,
@@ -492,6 +498,12 @@ impl<'a> TextArea<'a> {
ctrl: false,
alt: true,
..
}
| Input {
key: Key::Delete,
ctrl: true,
alt: false,
..
} => self.delete_next_word(),
Input {
key: Key::Char('n'),
@@ -3294,4 +3306,95 @@ mod tests {
assert!(panic.is_err());
}
fn key_input(key: Key, ctrl: bool, alt: bool) -> Input {
Input {
key,
ctrl,
alt,
shift: false,
}
}
#[test]
fn ctrl_backspace_deletes_word_before_cursor() {
let mut textarea = TextArea::from(["aaa bbb ccc"]);
textarea.move_cursor(CursorMove::End);
assert!(textarea.input(key_input(Key::Backspace, true, false)));
assert_eq!(textarea.lines(), ["aaa bbb "]);
assert_eq!(textarea.cursor(), (0, 8));
}
#[test]
fn ctrl_backspace_at_whitespace_skips_run_and_deletes_previous_word() {
let mut textarea = TextArea::from(["aaa bbb"]);
textarea.move_cursor(CursorMove::End);
textarea.input(key_input(Key::Backspace, true, false));
assert_eq!(textarea.lines(), ["aaa "]);
assert_eq!(textarea.cursor(), (0, 6));
}
#[test]
fn ctrl_delete_deletes_word_after_cursor() {
let mut textarea = TextArea::from(["aaa bbb ccc"]);
assert!(textarea.input(key_input(Key::Delete, true, false)));
assert_eq!(textarea.lines(), [" bbb ccc"]);
assert_eq!(textarea.cursor(), (0, 0));
}
#[test]
fn ctrl_delete_at_end_of_word_deletes_next_word() {
let mut textarea = TextArea::from(["aaa bbb ccc"]);
textarea.move_cursor(CursorMove::Jump(0, 4));
assert!(textarea.input(key_input(Key::Delete, true, false)));
assert_eq!(textarea.lines(), ["aaa ccc"]);
assert_eq!(textarea.cursor(), (0, 4));
}
#[test]
fn plain_backspace_still_deletes_single_char() {
let mut textarea = TextArea::from(["aaa bbb"]);
textarea.move_cursor(CursorMove::End);
assert!(textarea.input(key_input(Key::Backspace, false, false)));
assert_eq!(textarea.lines(), ["aaa bb"]);
}
#[test]
fn plain_delete_still_deletes_single_char() {
let mut textarea = TextArea::from(["aaa bbb"]);
assert!(textarea.input(key_input(Key::Delete, false, false)));
assert_eq!(textarea.lines(), ["aa bbb"]);
}
#[test]
fn alt_backspace_still_deletes_word() {
let mut textarea = TextArea::from(["aaa bbb ccc"]);
textarea.move_cursor(CursorMove::End);
assert!(textarea.input(key_input(Key::Backspace, false, true)));
assert_eq!(textarea.lines(), ["aaa bbb "]);
}
#[test]
fn ctrl_w_still_deletes_word() {
let mut textarea = TextArea::from(["aaa bbb ccc"]);
textarea.move_cursor(CursorMove::End);
assert!(textarea.input(key_input(Key::Char('w'), true, false)));
assert_eq!(textarea.lines(), ["aaa bbb "]);
}
}