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
//! The editing commands an [`Editor`](crate::Editor) understands.
/// One editing command for an [`Editor`](crate::Editor).
///
/// `Edit` is the boundary between the terminal and the editor. The host reads
/// key events however its platform delivers them — a raw-mode terminal library,
/// a GUI text field, a test script — and maps each one to an `Edit`; the editor
/// applies it to the line and reports whether anything changed. Keeping the
/// mapping on the host's side means the editor never touches a terminal and
/// any keymap (Emacs, Vi-style, custom) is a lookup table away.
///
/// Motions and deletions work in *display units*: a visible character together
/// with any zero-width characters attached to it, such as a combining accent.
/// The cursor never stops inside a unit. A *word* is a run of identifier
/// characters (Unicode `XID_Continue`: letters, digits, `_`, combining marks);
/// everything else separates words.
///
/// The usual Emacs/readline bindings are noted on each variant as a guide; they
/// are not built in.
///
/// The enum is `#[non_exhaustive]`, so new commands can arrive in a minor
/// release. Hosts build `Edit` values rather than matching on them, so this
/// costs nothing in practice.
///
/// # Examples
///
/// ```
/// use repl_lang::{Edit, Editor};
///
/// let mut editor = Editor::new();
/// for c in "print x".chars() {
/// editor.apply(Edit::Insert(c));
/// }
/// assert!(editor.apply(Edit::WordLeft)); // cursor before `x`
/// assert!(editor.apply(Edit::KillToStart)); // removes "print "
/// assert_eq!(editor.line(), "x");
/// assert!(editor.apply(Edit::Yank)); // and puts it back
/// assert_eq!(editor.line(), "print x");
/// ```