1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! Word-wise editing chords: ONE spelling table for [`TextInput`] and
//! [`TextArea`] (first-app/1310).
//!
//! The two widgets already knew what a word jump MEANS; what they did
//! not know is how many ways a terminal spells one. The same physical
//! gesture — "move by word" — reaches an app as three unrelated events
//! depending on the emulator and its settings, and a widget that
//! recognizes only one of them looks broken on the other two:
//!
//! The table is CODEX's default editor keymap, adopted verbatim
//! (`codex-rs/tui/src/keymap.rs`, `EditorKeymap` defaults) so a user
//! moving between the two feels no difference:
//!
//! | Codex binding | Gesture | Reaches us as |
//! |---|---|---|
//! | `move_word_left` | Alt+b, Alt+←, Ctrl+← | `Char('b')`+ALT, `Left`+ALT, `Left`+CTRL |
//! | `move_word_right` | Alt+f, Alt+→, Ctrl+→ | `Char('f')`+ALT, `Right`+ALT, `Right`+CTRL |
//! | `delete_backward_word` | Alt+Backspace, Ctrl+Backspace, Ctrl+W | `Backspace`+ALT/CTRL, `Char('w')`+CTRL |
//! | `delete_forward_word` | Alt+Delete, Ctrl+Delete, Alt+d | `Delete`+ALT/CTRL, `Char('d')`+ALT |
//!
//! Three spellings per gesture is not redundancy: macOS has no
//! Option-arrow escape of its own, so its terminals borrow readline's
//! `ESC b`/`ESC f` (iTerm2 ships exactly that in its "Natural Text
//! Editing" preset), while `CSI 1;3D` is the kitty/WezTerm/ghostty
//! form and `CSI 1;5D` the Linux/Windows one. Codex binds all three for
//! that reason, and so do we.
//!
//! Line start/end (`move_line_start` / `move_line_end`: Home/Ctrl+A,
//! End/Ctrl+E) live in the widgets' own key match, next to the
//! Home/End arms they share behavior with.
//!
//! SHIFT is deliberately not part of any pattern: it rides along to
//! extend the selection (`CSI 1;4D` = Shift+Alt+Left), and both widgets
//! already grow their selection from the modifier. Matching on the
//! word bit alone keeps "extend by word" working for free.
//!
//! ## What this costs an app
//!
//! A focused editor now CONSUMES `Alt+b`/`Alt+f`/`Alt+d` and `Ctrl+W`,
//! which previously fell through to global actions. That is the price
//! of the feature — those are editing chords wherever text has focus,
//! exactly as in readline, and they reach the keymap normally whenever
//! no editor holds focus.
//!
//! OWNER: REACT (input widgets).
use crate;
/// A word-wise editing gesture, resolved from every spelling a terminal
/// might use for it.
pub
/// Classify one key event as a word-wise gesture, or `None` when it is
/// ordinary input. See the module table for the spellings and why each
/// one exists.
pub