diff --git a/client/src/ui/handlers/event.rs b/client/src/ui/handlers/event.rs index 1734bc4..4fe5584 100644 --- a/client/src/ui/handlers/event.rs +++ b/client/src/ui/handlers/event.rs @@ -88,7 +88,17 @@ impl EventHandler { ]; let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = self.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !self.is_edit_mode && !current_input.is_empty() { + current_input.len() - 1 + } else { + current_input.len() + }; + let max_cursor_pos = if !self.is_edit_mode && !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + current_input.len() + }; + form_state.current_cursor_pos = self.ideal_cursor_column.min(max_cursor_pos); form_state.has_unsaved_changes = false; self.command_message = format!("Loaded entry {}", *current_position); } @@ -129,7 +139,12 @@ impl EventHandler { ]; let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = self.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !self.is_edit_mode && !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + current_input.len() + }; + form_state.current_cursor_pos = self.ideal_cursor_column.min(max_cursor_pos); form_state.has_unsaved_changes = false; self.command_message = format!("Loaded entry {}", *current_position); } @@ -157,7 +172,7 @@ impl EventHandler { } "move_right" => { let current_input = form_state.get_current_input(); - // Change this line to prevent moving past the last character + // Only move right if there are characters and we're not at the last one if !current_input.is_empty() && form_state.current_cursor_pos < current_input.len() - 1 { form_state.current_cursor_pos += 1; } @@ -172,13 +187,23 @@ impl EventHandler { form_state.current_field = form_state.current_field.saturating_sub(1); } let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = self.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + 0 + }; + form_state.current_cursor_pos = self.ideal_cursor_column.min(max_cursor_pos); return Ok((false, "".to_string())); } "move_down" => { form_state.current_field = (form_state.current_field + 1) % form_state.fields.len(); let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = self.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + 0 + }; + form_state.current_cursor_pos = self.ideal_cursor_column.min(max_cursor_pos); return Ok((false, "".to_string())); } _ => {} @@ -336,7 +361,12 @@ impl EventHandler { KeyCode::Down => { form_state.current_field = (form_state.current_field + 1) % form_state.fields.len(); let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = self.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !self.is_edit_mode && !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + current_input.len() + }; + form_state.current_cursor_pos = self.ideal_cursor_column.min(max_cursor_pos); } KeyCode::Up => { if form_state.current_field == 0 { @@ -345,7 +375,12 @@ impl EventHandler { form_state.current_field = form_state.current_field.saturating_sub(1); } let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = self.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !self.is_edit_mode && !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + current_input.len() + }; + form_state.current_cursor_pos = self.ideal_cursor_column.min(max_cursor_pos); } KeyCode::Tab => { if key.modifiers.contains(KeyModifiers::SHIFT) { @@ -358,7 +393,12 @@ impl EventHandler { form_state.current_field = (form_state.current_field + 1) % form_state.fields.len(); } let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = self.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !self.is_edit_mode && !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + current_input.len() + }; + form_state.current_cursor_pos = self.ideal_cursor_column.min(max_cursor_pos); } KeyCode::BackTab => { if form_state.current_field == 0 { @@ -367,12 +407,22 @@ impl EventHandler { form_state.current_field = form_state.current_field.saturating_sub(1); } let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = self.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !self.is_edit_mode && !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + current_input.len() + }; + form_state.current_cursor_pos = self.ideal_cursor_column.min(max_cursor_pos); } KeyCode::Enter => { form_state.current_field = (form_state.current_field + 1) % form_state.fields.len(); let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = self.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !self.is_edit_mode && !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + current_input.len() + }; + form_state.current_cursor_pos = self.ideal_cursor_column.min(max_cursor_pos); } KeyCode::Char(c) => { let cursor_pos = form_state.current_cursor_pos; diff --git a/client/src/ui/handlers/ui.rs b/client/src/ui/handlers/ui.rs index 3982e90..1097b8a 100644 --- a/client/src/ui/handlers/ui.rs +++ b/client/src/ui/handlers/ui.rs @@ -66,6 +66,15 @@ pub async fn run_ui() -> Result<(), Box> { // Handle position changes and update form state if !event_handler.is_edit_mode { + let current_input = form_state.get_current_input(); + let max_cursor_pos = if !current_input.is_empty() { + current_input.len() - 1 // Limit to last character in readonly mode + } else { + 0 + }; + form_state.current_cursor_pos = event_handler.ideal_cursor_column.min(max_cursor_pos); + + // Ensure position never exceeds total_count + 1 if app_state.current_position > total_count + 1 { app_state.current_position = total_count + 1; @@ -101,7 +110,12 @@ pub async fn run_ui() -> Result<(), Box> { ]; let current_input = form_state.get_current_input(); - form_state.current_cursor_pos = event_handler.ideal_cursor_column.min(current_input.len()); + let max_cursor_pos = if !event_handler.is_edit_mode && !current_input.is_empty() { + current_input.len() - 1 // In readonly mode, limit to last character + } else { + current_input.len() + }; + form_state.current_cursor_pos = event_handler.ideal_cursor_column.min(max_cursor_pos); form_state.has_unsaved_changes = false; event_handler.command_message = format!("Loaded entry {}", app_state.current_position); }