1use gpui::Keystroke;
10
11use super::edit::TextEdit;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum KeyOutcome {
16 Submit,
18 Cancel,
20 Edited,
22 Pass,
24}
25
26pub fn apply_key(edit: &mut TextEdit, ks: &Keystroke) -> KeyOutcome {
35 let outcome = apply_nav(edit, ks);
36 if outcome != KeyOutcome::Pass {
37 return outcome;
38 }
39 if !ks.modifiers.platform && !ks.modifiers.control {
44 if let Some(text) = ks.key_char.as_deref() {
45 let text: String = text.chars().filter(|c| !c.is_control()).collect();
46 if !text.is_empty() {
47 edit.insert(&text);
48 return KeyOutcome::Edited;
49 }
50 }
51 }
52 KeyOutcome::Pass
53}
54
55pub fn apply_nav(edit: &mut TextEdit, ks: &Keystroke) -> KeyOutcome {
59 let m = &ks.modifiers;
60 match ks.key.as_str() {
61 "enter" => return KeyOutcome::Submit,
62 "escape" => return KeyOutcome::Cancel,
63 "a" if m.platform => {
65 edit.select_all();
66 return KeyOutcome::Edited;
67 }
68 "left" => {
69 if !m.shift && !m.platform && !m.alt && edit.collapse_selection_start() {
70 return KeyOutcome::Edited;
71 }
72 edit.pre_move(m.shift);
73 if m.platform {
74 edit.home();
75 } else if m.alt {
76 edit.word_left();
77 } else {
78 edit.left();
79 }
80 return KeyOutcome::Edited;
81 }
82 "right" => {
83 if !m.shift && !m.platform && !m.alt && edit.collapse_selection_end() {
84 return KeyOutcome::Edited;
85 }
86 edit.pre_move(m.shift);
87 if m.platform {
88 edit.end();
89 } else if m.alt {
90 edit.word_right();
91 } else {
92 edit.right();
93 }
94 return KeyOutcome::Edited;
95 }
96 "up" | "home" => {
98 edit.pre_move(m.shift);
99 edit.home();
100 return KeyOutcome::Edited;
101 }
102 "down" | "end" => {
103 edit.pre_move(m.shift);
104 edit.end();
105 return KeyOutcome::Edited;
106 }
107 "backspace" => {
108 if m.platform {
109 edit.delete_to_start();
110 } else if m.alt {
111 edit.delete_word_back();
112 } else {
113 edit.backspace();
114 }
115 return KeyOutcome::Edited;
116 }
117 "delete" => {
118 if m.platform {
119 edit.delete_to_end();
120 } else if m.alt {
121 edit.delete_word_forward();
122 } else {
123 edit.delete();
124 }
125 return KeyOutcome::Edited;
126 }
127 "k" if m.control => {
128 edit.delete_to_end();
129 return KeyOutcome::Edited;
130 }
131 "a" if m.control => {
132 edit.home();
133 return KeyOutcome::Edited;
134 }
135 "e" if m.control => {
136 edit.end();
137 return KeyOutcome::Edited;
138 }
139 _ => {}
140 }
141 KeyOutcome::Pass
142}