@@ -13,6 +13,32 @@ pub struct KeyEvent {
13 pub modifiers: KeyModifiers,
13 pub modifiers: KeyModifiers,
17+ pub(crate) const BACKSPACE: &str = "backspace";
18+ pub(crate) const ENTER: &str = "ret";
19+ pub(crate) const LEFT: &str = "left";
20+ pub(crate) const RIGHT: &str = "right";
21+ pub(crate) const UP: &str = "up";
22+ pub(crate) const DOWN: &str = "down";
23+ pub(crate) const HOME: &str = "home";
24+ pub(crate) const END: &str = "end";
25+ pub(crate) const PAGEUP: &str = "pageup";
26+ pub(crate) const PAGEDOWN: &str = "pagedown";
27+ pub(crate) const TAB: &str = "tab";
28+ pub(crate) const BACKTAB: &str = "backtab";
29+ pub(crate) const DELETE: &str = "del";
30+ pub(crate) const INSERT: &str = "ins";
31+ pub(crate) const NULL: &str = "null";
32+ pub(crate) const ESC: &str = "esc";
33+ pub(crate) const SPACE: &str = "space";
34+ pub(crate) const LESS_THAN: &str = "lt";
35+ pub(crate) const GREATER_THAN: &str = "gt";
36+ pub(crate) const PLUS: &str = "plus";
37+ pub(crate) const MINUS: &str = "minus";
38+ pub(crate) const SEMICOLON: &str = "semicolon";
39+ pub(crate) const PERCENT: &str = "percent";
16impl fmt::Display for KeyEvent {
42impl fmt::Display for KeyEvent {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
18 f.write_fmt(format_args!(
44 f.write_fmt(format_args!(
@@ -34,28 +60,29 @@ impl fmt::Display for KeyEvent {
36 match self.code {
62 match self.code {
37− KeyCode::Backspace => f.write_str("backspace")?,
63+ KeyCode::Backspace => f.write_str(keys::BACKSPACE)?,
38− KeyCode::Enter => f.write_str("ret")?,
64+ KeyCode::Enter => f.write_str(keys::ENTER)?,
39− KeyCode::Left => f.write_str("left")?,
65+ KeyCode::Left => f.write_str(keys::LEFT)?,
40− KeyCode::Right => f.write_str("right")?,
66+ KeyCode::Right => f.write_str(keys::RIGHT)?,
41− KeyCode::Up => f.write_str("up")?,
67+ KeyCode::Up => f.write_str(keys::UP)?,
42− KeyCode::Down => f.write_str("down")?,
68+ KeyCode::Down => f.write_str(keys::DOWN)?,
43− KeyCode::Home => f.write_str("home")?,
69+ KeyCode::Home => f.write_str(keys::HOME)?,
44− KeyCode::End => f.write_str("end")?,
70+ KeyCode::End => f.write_str(keys::END)?,
45− KeyCode::PageUp => f.write_str("pageup")?,
71+ KeyCode::PageUp => f.write_str(keys::PAGEUP)?,
46− KeyCode::PageDown => f.write_str("pagedown")?,
72+ KeyCode::PageDown => f.write_str(keys::PAGEDOWN)?,
47− KeyCode::Tab => f.write_str("tab")?,
73+ KeyCode::Tab => f.write_str(keys::TAB)?,
48− KeyCode::BackTab => f.write_str("backtab")?,
74+ KeyCode::BackTab => f.write_str(keys::BACKTAB)?,
49− KeyCode::Delete => f.write_str("del")?,
75+ KeyCode::Delete => f.write_str(keys::DELETE)?,
50− KeyCode::Insert => f.write_str("ins")?,
76+ KeyCode::Insert => f.write_str(keys::INSERT)?,
51− KeyCode::Null => f.write_str("null")?,
77+ KeyCode::Null => f.write_str(keys::NULL)?,
52− KeyCode::Esc => f.write_str("esc")?,
78+ KeyCode::Esc => f.write_str(keys::ESC)?,
79+ KeyCode::Char(' ') => f.write_str(keys::SPACE)?,
53− KeyCode::Char('<') => f.write_str("lt")?,
80+ KeyCode::Char('<') => f.write_str(keys::LESS_THAN)?,
54− KeyCode::Char('>') => f.write_str("gt")?,
81+ KeyCode::Char('>') => f.write_str(keys::GREATER_THAN)?,
55− KeyCode::Char('+') => f.write_str("plus")?,
82+ KeyCode::Char('+') => f.write_str(keys::PLUS)?,
56− KeyCode::Char('-') => f.write_str("minus")?,
83+ KeyCode::Char('-') => f.write_str(keys::MINUS)?,
57− KeyCode::Char(';') => f.write_str("semicolon")?,
84+ KeyCode::Char(';') => f.write_str(keys::SEMICOLON)?,
58− KeyCode::Char('%') => f.write_str("percent")?,
85+ KeyCode::Char('%') => f.write_str(keys::PERCENT)?,
59 KeyCode::F(i) => f.write_fmt(format_args!("F{}", i))?,
86 KeyCode::F(i) => f.write_fmt(format_args!("F{}", i))?,
60 KeyCode::Char(c) => f.write_fmt(format_args!("{}", c))?,
87 KeyCode::Char(c) => f.write_fmt(format_args!("{}", c))?,
@@ -63,34 +90,83 @@ impl fmt::Display for KeyEvent {
93+impl unicode_width::UnicodeWidthStr for KeyEvent {
94+ fn width(&self) -> usize {
95+ use unicode_width::UnicodeWidthChar;
96+ let mut width = match self.code {
97+ KeyCode::Backspace => keys::BACKSPACE.len(),
98+ KeyCode::Enter => keys::ENTER.len(),
99+ KeyCode::Left => keys::LEFT.len(),
100+ KeyCode::Right => keys::RIGHT.len(),
101+ KeyCode::Up => keys::UP.len(),
102+ KeyCode::Down => keys::DOWN.len(),
103+ KeyCode::Home => keys::HOME.len(),
104+ KeyCode::End => keys::END.len(),
105+ KeyCode::PageUp => keys::PAGEUP.len(),
106+ KeyCode::PageDown => keys::PAGEDOWN.len(),
107+ KeyCode::Tab => keys::TAB.len(),
108+ KeyCode::BackTab => keys::BACKTAB.len(),
109+ KeyCode::Delete => keys::DELETE.len(),
110+ KeyCode::Insert => keys::INSERT.len(),
111+ KeyCode::Null => keys::NULL.len(),
112+ KeyCode::Esc => keys::ESC.len(),
113+ KeyCode::Char(' ') => keys::SPACE.len(),
114+ KeyCode::Char('<') => keys::LESS_THAN.len(),
115+ KeyCode::Char('>') => keys::GREATER_THAN.len(),
116+ KeyCode::Char('+') => keys::PLUS.len(),
117+ KeyCode::Char('-') => keys::MINUS.len(),
118+ KeyCode::Char(';') => keys::SEMICOLON.len(),
119+ KeyCode::Char('%') => keys::PERCENT.len(),
120+ KeyCode::F(1..=9) => 2,
122+ KeyCode::Char(c) => c.width().unwrap_or(0),
124+ if self.modifiers.contains(KeyModifiers::SHIFT) {
127+ if self.modifiers.contains(KeyModifiers::ALT) {
130+ if self.modifiers.contains(KeyModifiers::CONTROL) {
136+ fn width_cjk(&self) -> usize {
66impl std::str::FromStr for KeyEvent {
141impl std::str::FromStr for KeyEvent {
67 type Err = Error;
142 type Err = Error;
69 fn from_str(s: &str) -> Result<Self, Self::Err> {
144 fn from_str(s: &str) -> Result<Self, Self::Err> {
70 let mut tokens: Vec<_> = s.split('-').collect();
145 let mut tokens: Vec<_> = s.split('-').collect();
71 let code = match tokens.pop().ok_or_else(|| anyhow!("Missing key code"))? {
146 let code = match tokens.pop().ok_or_else(|| anyhow!("Missing key code"))? {
72− "backspace" => KeyCode::Backspace,
147+ keys::BACKSPACE => KeyCode::Backspace,
73− "space" => KeyCode::Char(' '),
74− "ret" => KeyCode::Enter,
148+ keys::ENTER => KeyCode::Enter,
75− "lt" => KeyCode::Char('<'),
76− "gt" => KeyCode::Char('>'),
77− "plus" => KeyCode::Char('+'),
78− "minus" => KeyCode::Char('-'),
79− "semicolon" => KeyCode::Char(';'),
80− "percent" => KeyCode::Char('%'),
81− "left" => KeyCode::Left,
149+ keys::LEFT => KeyCode::Left,
82− "right" => KeyCode::Right,
150+ keys::RIGHT => KeyCode::Right,
151+ keys::UP => KeyCode::Up,
83− "up" => KeyCode::Down,
152+ keys::DOWN => KeyCode::Down,
84− "home" => KeyCode::Home,
153+ keys::HOME => KeyCode::Home,
85− "end" => KeyCode::End,
154+ keys::END => KeyCode::End,
86− "pageup" => KeyCode::PageUp,
155+ keys::PAGEUP => KeyCode::PageUp,
87− "pagedown" => KeyCode::PageDown,
156+ keys::PAGEDOWN => KeyCode::PageDown,
88− "tab" => KeyCode::Tab,
157+ keys::TAB => KeyCode::Tab,
89− "backtab" => KeyCode::BackTab,
158+ keys::BACKTAB => KeyCode::BackTab,
90− "del" => KeyCode::Delete,
159+ keys::DELETE => KeyCode::Delete,
91− "ins" => KeyCode::Insert,
160+ keys::INSERT => KeyCode::Insert,
92− "null" => KeyCode::Null,
161+ keys::NULL => KeyCode::Null,
93− "esc" => KeyCode::Esc,
162+ keys::ESC => KeyCode::Esc,
163+ keys::SPACE => KeyCode::Char(' '),
164+ keys::LESS_THAN => KeyCode::Char('<'),
165+ keys::GREATER_THAN => KeyCode::Char('>'),
166+ keys::PLUS => KeyCode::Char('+'),
167+ keys::MINUS => KeyCode::Char('-'),
168+ keys::SEMICOLON => KeyCode::Char(';'),
169+ keys::PERCENT => KeyCode::Char('%'),
94 single if single.len() == 1 => KeyCode::Char(single.chars().next().unwrap()),
170 single if single.len() == 1 => KeyCode::Char(single.chars().next().unwrap()),
95 function if function.len() > 1 && function.starts_with('F') => {
171 function if function.len() > 1 && function.starts_with('F') => {
96 let function: String = function.chars().skip(1).collect();
172 let function: String = function.chars().skip(1).collect();