From 26b899df16d74f26d39e315e7d276cb7842164d4 Mon Sep 17 00:00:00 2001 From: filipriec Date: Wed, 16 Apr 2025 09:48:39 +0200 Subject: [PATCH] fixed highlight logic --- client/src/components/handlers/canvas.rs | 39 +++++++++++++++--------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/client/src/components/handlers/canvas.rs b/client/src/components/handlers/canvas.rs index e69d129..12b2fba 100644 --- a/client/src/components/handlers/canvas.rs +++ b/client/src/components/handlers/canvas.rs @@ -23,7 +23,7 @@ pub fn render_canvas( is_edit_mode: bool, highlight_state: &HighlightState, // Using the enum state ) -> Option { - // ... (column split, container styling, block dimensions - unchanged) ... + // ... (setup code remains the same) ... let columns = Layout::default() .direction(Direction::Horizontal) .constraints([Constraint::Percentage(30), Constraint::Percentage(70)]) @@ -93,9 +93,11 @@ pub fn render_canvas( } HighlightState::Characterwise { anchor } => { // --- Character-wise Highlight Logic --- - let (anchor_field, anchor_char) = *anchor; // Dereference the tuple from the enum + let (anchor_field, anchor_char) = *anchor; let start_field = min(anchor_field, *current_field_idx); let end_field = max(anchor_field, *current_field_idx); + + // Use start_char and end_char consistently let (start_char, end_char) = if anchor_field == *current_field_idx { (min(anchor_char, current_cursor_pos), max(anchor_char, current_cursor_pos)) } else if anchor_field < *current_field_idx { @@ -111,17 +113,22 @@ pub fn render_canvas( if i >= start_field && i <= end_field { // This line is within the character-wise highlight range if start_field == end_field { // Case 1: Single Line Highlight - let safe_start = start_char.min(text_len); - let safe_end = end_char.min(text_len); - let before: String = text.chars().take(safe_start).collect(); - let highlighted: String = text.chars().skip(safe_start).take(safe_end - safe_start).collect(); - let after: String = text.chars().skip(safe_end).collect(); + // Use start_char and end_char here + let clamped_start = start_char.min(text_len); + let clamped_end = end_char.min(text_len); // Use text_len for slicing logic + + let before: String = text.chars().take(clamped_start).collect(); + let highlighted: String = text.chars().skip(clamped_start).take(clamped_end.saturating_sub(clamped_start) + 1).collect(); + // Define 'after' here + let after: String = text.chars().skip(clamped_end + 1).collect(); + line = Line::from(vec![ Span::styled(before, normal_style_in_highlight), Span::styled(highlighted, highlight_style), - Span::styled(after, normal_style_in_highlight), + Span::styled(after, normal_style_in_highlight), // Use defined 'after' ]); } else if i == start_field { // Case 2: Multi-Line Highlight - Start Line + // Use start_char here let safe_start = start_char.min(text_len); let before: String = text.chars().take(safe_start).collect(); let highlighted: String = text.chars().skip(safe_start).collect(); @@ -129,28 +136,30 @@ pub fn render_canvas( Span::styled(before, normal_style_in_highlight), Span::styled(highlighted, highlight_style), ]); - } else if i == end_field { // Case 4: Multi-Line Highlight - End Line - let safe_end = end_char.min(text_len); - let highlighted: String = text.chars().take(safe_end).collect(); - let after: String = text.chars().skip(safe_end).collect(); + } else if i == end_field { // Case 3: Multi-Line Highlight - End Line (Corrected index) + // Use end_char here + let safe_end_inclusive = if text_len > 0 { end_char.min(text_len - 1) } else { 0 }; + let highlighted: String = text.chars().take(safe_end_inclusive + 1).collect(); + let after: String = text.chars().skip(safe_end_inclusive + 1).collect(); line = Line::from(vec![ Span::styled(highlighted, highlight_style), Span::styled(after, normal_style_in_highlight), ]); - } else { // Case 3: Multi-Line Highlight - Middle Line + } else { // Case 4: Multi-Line Highlight - Middle Line (Corrected index) line = Line::from(Span::styled(text, highlight_style)); // Highlight whole line } } else { // Case 5: Line Outside Character-wise Highlight Range line = Line::from(Span::styled( text, + // Use normal styling (active or inactive) if is_active { normal_style_in_highlight } else { normal_style_outside } )); } } HighlightState::Linewise { anchor_line } => { // --- Linewise Highlight Logic --- - let start_field = min(*anchor_line, *current_field_idx); // Dereference anchor_line - let end_field = max(*anchor_line, *current_field_idx); // Dereference anchor_line + let start_field = min(*anchor_line, *current_field_idx); + let end_field = max(*anchor_line, *current_field_idx); let highlight_style = Style::default().fg(theme.highlight).bg(theme.highlight_bg).add_modifier(Modifier::BOLD); let normal_style_in_highlight = Style::default().fg(theme.highlight); let normal_style_outside = Style::default().fg(theme.fg);