sql_cli/ui/traits/
input_ops.rs1use crate::app_state_container::AppStateContainer;
2use crate::buffer::{AppMode, BufferAPI, BufferManager, EditMode};
3use crate::cursor_manager::CursorManager;
4use crate::ui::utils::text_operations::{self, CursorMovementResult, TextOperationResult};
5pub trait InputBehavior {
10 fn buffer_manager(&mut self) -> &mut BufferManager;
12 fn cursor_manager(&mut self) -> &mut CursorManager;
13 fn set_input_text_with_cursor(&mut self, text: String, cursor: usize);
14 fn state_container(&self) -> &AppStateContainer;
15 fn state_container_mut(&mut self) -> &mut AppStateContainer; fn buffer_mut(&mut self) -> &mut dyn BufferAPI;
17
18 fn set_mode_with_sync(&mut self, mode: AppMode, trigger: &str);
20
21 fn get_current_input(&mut self) -> (String, usize) {
23 if let Some(buffer) = self.buffer_manager().current() {
24 (buffer.get_input_text(), buffer.get_input_cursor_position())
25 } else {
26 (String::new(), 0)
27 }
28 }
29
30 fn apply_text_result(&mut self, result: TextOperationResult) {
32 if let Some(buffer) = self.buffer_manager().current_mut() {
33 buffer.set_input_text(result.new_text.clone());
35 buffer.set_input_cursor_position(result.new_cursor_position);
36
37 if let Some(killed) = result.killed_text {
39 buffer.set_kill_ring(killed);
40 }
41
42 if buffer.get_edit_mode() == EditMode::SingleLine {
44 self.set_input_text_with_cursor(result.new_text, result.new_cursor_position);
45 self.cursor_manager()
46 .set_position(result.new_cursor_position);
47 }
48 }
49 }
50
51 fn apply_cursor_result(&mut self, result: CursorMovementResult) {
53 if let Some(buffer) = self.buffer_manager().current_mut() {
54 buffer.set_input_cursor_position(result.new_position);
55
56 if buffer.get_edit_mode() == EditMode::SingleLine {
58 let text = buffer.get_input_text();
59 self.set_input_text_with_cursor(text, result.new_position);
60 self.cursor_manager().set_position(result.new_position);
61 }
62 }
63 }
64
65 fn kill_line(&mut self) {
69 if let Some(buffer) = self.buffer_manager().current_mut() {
70 buffer.save_state_for_undo();
71 }
72
73 let (text, cursor) = self.get_current_input();
74 let result = text_operations::kill_line(&text, cursor);
75 self.apply_text_result(result);
76 }
77
78 fn kill_line_backward(&mut self) {
80 if let Some(buffer) = self.buffer_manager().current_mut() {
81 buffer.save_state_for_undo();
82 }
83
84 let (text, cursor) = self.get_current_input();
85 let result = text_operations::kill_line_backward(&text, cursor);
86 self.apply_text_result(result);
87 }
88
89 fn delete_word_backward(&mut self) {
91 if let Some(buffer) = self.buffer_manager().current_mut() {
92 buffer.save_state_for_undo();
93 }
94
95 let (text, cursor) = self.get_current_input();
96 let result = text_operations::delete_word_backward(&text, cursor);
97 self.apply_text_result(result);
98 }
99
100 fn delete_word_forward(&mut self) {
102 if let Some(buffer) = self.buffer_manager().current_mut() {
103 buffer.save_state_for_undo();
104 }
105
106 let (text, cursor) = self.get_current_input();
107 let result = text_operations::delete_word_forward(&text, cursor);
108 self.apply_text_result(result);
109 }
110
111 fn move_cursor_word_backward(&mut self) {
115 let (text, cursor) = self.get_current_input();
116 let result = text_operations::move_word_backward(&text, cursor);
117 self.apply_cursor_result(result);
118 }
119
120 fn move_cursor_word_forward(&mut self) {
122 let (text, cursor) = self.get_current_input();
123 let result = text_operations::move_word_forward(&text, cursor);
124 self.apply_cursor_result(result);
125 }
126
127 fn jump_to_prev_token(&mut self) {
129 let (text, cursor) = self.get_current_input();
130 let result = text_operations::jump_to_prev_token(&text, cursor);
131 self.apply_cursor_result(result);
132 }
133
134 fn jump_to_next_token(&mut self) {
136 let (text, cursor) = self.get_current_input();
137 let result = text_operations::jump_to_next_token(&text, cursor);
138 self.apply_cursor_result(result);
139 }
140
141 fn insert_char(&mut self, ch: char) {
145 if let Some(buffer) = self.buffer_manager().current_mut() {
146 buffer.save_state_for_undo();
147 }
148
149 let (text, cursor) = self.get_current_input();
150 let result = text_operations::insert_char(&text, cursor, ch);
151 self.apply_text_result(result);
152 }
153
154 fn delete_char(&mut self) {
156 if let Some(buffer) = self.buffer_manager().current_mut() {
157 buffer.save_state_for_undo();
158 }
159
160 let (text, cursor) = self.get_current_input();
161 let result = text_operations::delete_char(&text, cursor);
162 self.apply_text_result(result);
163 }
164
165 fn backspace(&mut self) {
167 if let Some(buffer) = self.buffer_manager().current_mut() {
168 buffer.save_state_for_undo();
169 }
170
171 let (text, cursor) = self.get_current_input();
172 let result = text_operations::backspace(&text, cursor);
173 self.apply_text_result(result);
174 }
175
176 fn clear_input(&mut self) {
178 if let Some(buffer) = self.buffer_manager().current_mut() {
179 buffer.save_state_for_undo();
180 }
181
182 let result = text_operations::clear_text();
183 self.apply_text_result(result);
184 }
185
186 fn get_jump_to_row_input(&self) -> String {
190 self.state_container().jump_to_row().input.clone()
191 }
192
193 fn set_jump_to_row_input(&mut self, input: String) {
195 self.state_container_mut().jump_to_row_mut().input = input;
197 }
198
199 fn clear_jump_to_row_input(&mut self) {
201 self.state_container_mut().jump_to_row_mut().input.clear();
203 }
204
205 fn process_jump_to_row_key(&mut self, key: crossterm::event::KeyEvent) -> bool {
207 use crossterm::event::KeyCode;
208
209 match key.code {
210 KeyCode::Esc => {
211 self.set_mode_with_sync(AppMode::Results, "escape_from_jump_to_row");
213 self.clear_jump_to_row_input();
214
215 self.state_container_mut().jump_to_row_mut().is_active = false;
217 true
218 }
219 KeyCode::Backspace => {
220 let mut input = self.get_jump_to_row_input();
221 input.pop();
222 self.set_jump_to_row_input(input);
223 true
224 }
225 KeyCode::Char(c) if c.is_ascii_digit() => {
226 let mut input = self.get_jump_to_row_input();
227 input.push(c);
228 self.set_jump_to_row_input(input);
229 true
230 }
231 _ => false,
232 }
233 }
234}