p2p_chat/ui/log_mode/input/
keys.rs

1//! This module contains key event handling logic for the log UI mode.
2use crate::ui::log_mode::LogMode;
3use crate::ui::{UIAction, UIState};
4use anyhow::Result;
5use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
6use tokio::sync::mpsc;
7use tracing::debug;
8
9impl LogMode {
10    /// Handles a key event in log mode.
11    ///
12    /// This function processes various key presses, including typing characters,
13    /// navigating input history, moving the cursor, and scrolling through logs.
14    ///
15    /// # Arguments
16    ///
17    /// * `state` - The current UI state.
18    /// * `key` - The `KeyEvent` to handle.
19    /// * `_action_tx` - The sender for dispatching UI actions (unused in log mode input).
20    ///
21    /// # Errors
22    ///
23    /// This function returns an error if a command execution fails.
24    pub async fn handle_key(
25        &mut self,
26        state: &mut UIState,
27        key: KeyEvent,
28        _action_tx: &mpsc::UnboundedSender<UIAction>,
29    ) -> Result<()> {
30        match key.code {
31            KeyCode::Enter => {
32                if !state.input_buffer.trim().is_empty() {
33                    let input = state.input_buffer.clone();
34                    self.input_history.push(input.clone());
35                    self.history_index = None;
36
37                    self.execute_log_command(&input, state).await?;
38
39                    state.input_buffer.clear();
40                    state.cursor_pos = 0;
41                }
42            }
43            KeyCode::Char(c) => {
44                state.safe_insert_char(c);
45                self.history_index = None;
46            }
47            KeyCode::Backspace => {
48                if state.safe_remove_char_before() {
49                    self.history_index = None;
50                }
51            }
52            KeyCode::Delete => {
53                state.safe_remove_char_at();
54            }
55            KeyCode::Left => {
56                state.safe_cursor_left();
57            }
58            KeyCode::Right => {
59                state.safe_cursor_right();
60            }
61            KeyCode::Home => {
62                if key.modifiers.contains(KeyModifiers::CONTROL) {
63                    state.horizontal_scroll_offset =
64                        state.horizontal_scroll_offset.saturating_sub(10);
65                } else {
66                    state.safe_cursor_home();
67                }
68            }
69            KeyCode::End => {
70                if key.modifiers.contains(KeyModifiers::CONTROL) {
71                    state.horizontal_scroll_offset =
72                        state.horizontal_scroll_offset.saturating_add(10);
73                } else {
74                    state.safe_cursor_end();
75                }
76            }
77            KeyCode::Up => {
78                if key.modifiers.contains(KeyModifiers::CONTROL) {
79                    self.navigate_history(state, true);
80                } else {
81                    state.log_scroll_offset = state.log_scroll_offset.saturating_add(1);
82                    state.update_log_scroll_state(state.terminal_size.1 as usize);
83                }
84            }
85            KeyCode::Down => {
86                if key.modifiers.contains(KeyModifiers::CONTROL) {
87                    self.navigate_history(state, false);
88                } else {
89                    state.log_scroll_offset = state.log_scroll_offset.saturating_sub(1);
90                    state.update_log_scroll_state(state.terminal_size.1 as usize);
91                }
92            }
93            KeyCode::PageUp => {
94                state.log_scroll_offset = state.log_scroll_offset.saturating_add(10);
95                state.update_log_scroll_state(state.terminal_size.1 as usize);
96            }
97            KeyCode::PageDown => {
98                state.log_scroll_offset = state.log_scroll_offset.saturating_sub(10);
99                state.update_log_scroll_state(state.terminal_size.1 as usize);
100            }
101            KeyCode::Esc => {
102                state.jump_to_bottom_log();
103            }
104            KeyCode::Tab => {
105                debug!("Tab pressed in log mode - autocompletion not yet implemented");
106            }
107            _ => {}
108        }
109
110        Ok(())
111    }
112}