tui_textarea/input/mod.rs
1#[cfg(any(feature = "crossterm", feature = "tuirs-crossterm"))]
2mod crossterm;
3#[cfg(any(feature = "termion", feature = "tuirs-termion"))]
4mod termion;
5#[cfg(feature = "termwiz")]
6mod termwiz;
7
8#[cfg(feature = "arbitrary")]
9use arbitrary::Arbitrary;
10#[cfg(feature = "serde")]
11use serde::{Deserialize, Serialize};
12
13/// Backend-agnostic key input kind.
14///
15/// This type is marked as `#[non_exhaustive]` since more keys may be supported in the future.
16#[non_exhaustive]
17#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq)]
18#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20pub enum Key {
21 /// Normal letter key input
22 Char(char),
23 /// F1, F2, F3, ... keys
24 F(u8),
25 /// Backspace key
26 Backspace,
27 /// Enter or return key
28 Enter,
29 /// Left arrow key
30 Left,
31 /// Right arrow key
32 Right,
33 /// Up arrow key
34 Up,
35 /// Down arrow key
36 Down,
37 /// Tab key
38 Tab,
39 /// Delete key
40 Delete,
41 /// Home key
42 Home,
43 /// End key
44 End,
45 /// Page up key
46 PageUp,
47 /// Page down key
48 PageDown,
49 /// Escape key
50 Esc,
51 /// Copy key. This key is supported by termwiz only
52 Copy,
53 /// Cut key. This key is supported by termwiz only
54 Cut,
55 /// Paste key. This key is supported by termwiz only
56 Paste,
57 /// Virtual key to scroll down by mouse
58 MouseScrollDown,
59 /// Virtual key to scroll up by mouse
60 MouseScrollUp,
61 /// An invalid key input (this key is always ignored by [`TextArea`](crate::TextArea))
62 Null,
63}
64
65impl Default for Key {
66 fn default() -> Self {
67 Key::Null
68 }
69}
70
71/// Backend-agnostic key input type.
72///
73/// When `crossterm`, `termion`, `termwiz` features are enabled, converting respective key input types into this
74/// `Input` type is defined.
75/// ```no_run
76/// use tui_textarea::{TextArea, Input, Key};
77/// use crossterm::event::{Event, read};
78///
79/// let event = read().unwrap();
80///
81/// // `Input::from` can convert backend-native event into `Input`
82/// let input = Input::from(event.clone());
83/// // or `Into::into`
84/// let input: Input = event.clone().into();
85/// // Conversion from `KeyEvent` value is also available
86/// if let Event::Key(key) = event {
87/// let input = Input::from(key);
88/// }
89/// ```
90///
91/// Creating `Input` instance directly can cause backend-agnostic input as follows.
92///
93/// ```
94/// use tui_textarea::{TextArea, Input, Key};
95///
96/// let mut textarea = TextArea::default();
97///
98/// // Input Ctrl+A
99/// textarea.input(Input {
100/// key: Key::Char('a'),
101/// ctrl: true,
102/// alt: false,
103/// shift: false,
104/// });
105/// ```
106#[derive(Debug, Clone, Default, PartialEq, Hash, Eq)]
107#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
108#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
109pub struct Input {
110 /// Typed key.
111 pub key: Key,
112 /// Ctrl modifier key. `true` means Ctrl key was pressed.
113 pub ctrl: bool,
114 /// Alt modifier key. `true` means Alt key was pressed.
115 pub alt: bool,
116 /// Shift modifier key. `true` means Shift key was pressed.
117 pub shift: bool,
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[allow(dead_code)]
125 pub(crate) fn input(key: Key, ctrl: bool, alt: bool, shift: bool) -> Input {
126 Input {
127 key,
128 ctrl,
129 alt,
130 shift,
131 }
132 }
133
134 #[test]
135 #[cfg(feature = "arbitrary")]
136 fn arbitrary_input() {
137 let mut u = arbitrary::Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
138 Input::arbitrary(&mut u).unwrap();
139 }
140
141 #[test]
142 #[cfg(feature = "arbitrary")]
143 fn arbitrary_key() {
144 let mut u = arbitrary::Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
145 Key::arbitrary(&mut u).unwrap();
146 }
147}