diff --git a/client/src/modes/handlers/edit.rs b/client/src/modes/handlers/edit.rs index b1dea55..d04e078 100644 --- a/client/src/modes/handlers/edit.rs +++ b/client/src/modes/handlers/edit.rs @@ -19,6 +19,11 @@ pub async fn handle_edit_event_internal( total_count: u64, grpc_client: &mut GrpcClient, ) -> Result> { + if let Some("enter_command_mode") = config.get_action_for_key_in_mode(&config.keybindings.global, key.code, key.modifiers) { + // Ignore in edit mode and process as normal input + handle_edit_specific_input(key, form_state, ideal_cursor_column); + return Ok(command_message.clone()); + } if let Some(action) = config.get_edit_action_for_key(key.code, key.modifiers) { return execute_edit_action( action, diff --git a/client/src/modes/handlers/event.rs b/client/src/modes/handlers/event.rs index 2e5bd89..3ec1d83 100644 --- a/client/src/modes/handlers/event.rs +++ b/client/src/modes/handlers/event.rs @@ -1,5 +1,5 @@ // src/modes/handlers/event.rs -use crossterm::event::{Event, KeyCode}; +use crossterm::event::Event; use crossterm::cursor::SetCursorStyle; use crate::tui::terminal::{ core::TerminalCore, @@ -52,7 +52,7 @@ impl EventHandler { if app_state.ui.show_intro { if let Event::Key(key) = event { let action = config.get_intro_action(key.code, key.modifiers); - + match action { Some("previous_option") => intro_state.previous_option(), Some("next_option") => intro_state.next_option(), @@ -81,6 +81,42 @@ impl EventHandler { ))); } + // Handle edit mode first to allow normal character input + if self.is_edit_mode { + if config.is_exit_edit_mode(key_code, modifiers) { + if form_state.has_unsaved_changes { + self.command_message = "Unsaved changes! Use :w to save or :q! to discard".to_string(); + return Ok((false, self.command_message.clone())); + } + self.is_edit_mode = false; + self.edit_mode_cooldown = true; + self.command_message = "Read-only mode".to_string(); + terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?; + + let current_input = form_state.get_current_input(); + if !current_input.is_empty() && form_state.current_cursor_pos >= current_input.len() { + form_state.current_cursor_pos = current_input.len() - 1; + self.ideal_cursor_column = form_state.current_cursor_pos; + } + return Ok((false, self.command_message.clone())); + } + + let result = edit::handle_edit_event_internal( + key, + config, + form_state, + &mut self.ideal_cursor_column, + &mut self.command_message, + &mut app_state.ui.is_saved, + current_position, + total_count, + grpc_client, + ).await?; + + self.key_sequence_tracker.reset(); + return Ok((false, result)); + } + // Global command mode activation let context_action = config.get_action_for_current_context( self.is_edit_mode, @@ -92,7 +128,6 @@ impl EventHandler { ); if let Some("enter_command_mode") = context_action { - if self.is_edit_mode { return Ok((false, String::new())); } self.command_mode = true; self.command_input.clear(); self.command_message.clear(); @@ -156,83 +191,48 @@ impl EventHandler { return Ok((should_exit, message)); } - if self.is_edit_mode { - if config.is_exit_edit_mode(key_code, modifiers) { - if form_state.has_unsaved_changes { - self.command_message = "Unsaved changes! Use :w to save or :q! to discard".to_string(); - return Ok((false, self.command_message.clone())); - } - self.is_edit_mode = false; - self.edit_mode_cooldown = true; - self.command_message = "Read-only mode".to_string(); - terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?; - - let current_input = form_state.get_current_input(); - if !current_input.is_empty() && form_state.current_cursor_pos >= current_input.len() { - form_state.current_cursor_pos = current_input.len() - 1; - self.ideal_cursor_column = form_state.current_cursor_pos; - } - return Ok((false, self.command_message.clone())); + if let Some(action) = config.get_read_only_action_for_key(key_code, modifiers) { + if action == "enter_command_mode" { + self.command_mode = true; + self.command_input.clear(); + self.command_message.clear(); + return Ok((false, String::new())); } - - let result = edit::handle_edit_event_internal( - key, - config, - form_state, - &mut self.ideal_cursor_column, - &mut self.command_message, - &mut app_state.ui.is_saved, - current_position, - total_count, - grpc_client, - ).await?; - - self.key_sequence_tracker.reset(); - return Ok((false, result)); - } else { - if let Some(action) = config.get_read_only_action_for_key(key_code, modifiers) { - if action == "enter_command_mode" { - self.command_mode = true; - self.command_input.clear(); - self.command_message.clear(); - return Ok((false, String::new())); - } - } - - if config.is_enter_edit_mode_before(key_code, modifiers) { - self.is_edit_mode = true; - self.edit_mode_cooldown = true; - self.command_message = "Edit mode".to_string(); - terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?; - return Ok((false, self.command_message.clone())); - } - - if config.is_enter_edit_mode_after(key_code, modifiers) { - let current_input = form_state.get_current_input(); - if !current_input.is_empty() && form_state.current_cursor_pos < current_input.len() { - form_state.current_cursor_pos += 1; - self.ideal_cursor_column = form_state.current_cursor_pos; - } - self.is_edit_mode = true; - self.edit_mode_cooldown = true; - self.command_message = "Edit mode (after cursor)".to_string(); - terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?; - return Ok((false, self.command_message.clone())); - } - - return read_only::handle_read_only_event( - key, - config, - form_state, - &mut self.key_sequence_tracker, - current_position, - total_count, - grpc_client, - &mut self.command_message, - &mut self.edit_mode_cooldown, - &mut self.ideal_cursor_column, - ).await; } + + if config.is_enter_edit_mode_before(key_code, modifiers) { + self.is_edit_mode = true; + self.edit_mode_cooldown = true; + self.command_message = "Edit mode".to_string(); + terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?; + return Ok((false, self.command_message.clone())); + } + + if config.is_enter_edit_mode_after(key_code, modifiers) { + let current_input = form_state.get_current_input(); + if !current_input.is_empty() && form_state.current_cursor_pos < current_input.len() { + form_state.current_cursor_pos += 1; + self.ideal_cursor_column = form_state.current_cursor_pos; + } + self.is_edit_mode = true; + self.edit_mode_cooldown = true; + self.command_message = "Edit mode (after cursor)".to_string(); + terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?; + return Ok((false, self.command_message.clone())); + } + + return read_only::handle_read_only_event( + key, + config, + form_state, + &mut self.key_sequence_tracker, + current_position, + total_count, + grpc_client, + &mut self.command_message, + &mut self.edit_mode_cooldown, + &mut self.ideal_cursor_column, + ).await; } self.edit_mode_cooldown = false;