highlight through many lines working
This commit is contained in:
@@ -56,6 +56,7 @@ enter_highlight_mode = ["v"]
|
|||||||
exit_highlight_mode = ["esc"]
|
exit_highlight_mode = ["esc"]
|
||||||
|
|
||||||
[keybindings.edit]
|
[keybindings.edit]
|
||||||
|
# BIG CHANGES NOW EXIT HANDLES EITHER IF THOSE
|
||||||
# exit_edit_mode = ["esc","ctrl+e"]
|
# exit_edit_mode = ["esc","ctrl+e"]
|
||||||
# exit_suggestion_mode = ["esc"]
|
# exit_suggestion_mode = ["esc"]
|
||||||
exit = ["esc", "ctrl+e"]
|
exit = ["esc", "ctrl+e"]
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ use ratatui::{
|
|||||||
};
|
};
|
||||||
use crate::config::colors::themes::Theme;
|
use crate::config::colors::themes::Theme;
|
||||||
use crate::state::pages::canvas_state::CanvasState;
|
use crate::state::pages::canvas_state::CanvasState;
|
||||||
|
use std::cmp::{min, max}; // Import min and max
|
||||||
|
|
||||||
pub fn render_canvas(
|
pub fn render_canvas(
|
||||||
f: &mut Frame,
|
f: &mut Frame,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
form_state: &impl CanvasState,
|
form_state: &impl CanvasState,
|
||||||
fields: &[&str],
|
fields: &[&str],
|
||||||
current_field: &usize,
|
current_field_idx: &usize, // Renamed for clarity
|
||||||
inputs: &[&String],
|
inputs: &[&String],
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
is_edit_mode: bool,
|
is_edit_mode: bool,
|
||||||
@@ -76,45 +77,83 @@ pub fn render_canvas(
|
|||||||
|
|
||||||
// Render inputs and cursor
|
// Render inputs and cursor
|
||||||
for (i, input) in inputs.iter().enumerate() {
|
for (i, input) in inputs.iter().enumerate() {
|
||||||
let is_active = i == *current_field;
|
let is_active = i == *current_field_idx;
|
||||||
let current_cursor_pos = form_state.current_cursor_pos();
|
let current_cursor_pos = form_state.current_cursor_pos();
|
||||||
|
let text = input.as_str();
|
||||||
|
let text_len = text.chars().count();
|
||||||
|
|
||||||
let line = if is_highlight_mode && highlight_anchor.is_some() {
|
let line: Line; // Determine the line content with spans
|
||||||
|
|
||||||
|
if is_highlight_mode && highlight_anchor.is_some() {
|
||||||
let (anchor_field, anchor_char) = highlight_anchor.unwrap();
|
let (anchor_field, anchor_char) = highlight_anchor.unwrap();
|
||||||
|
|
||||||
if i == anchor_field && i == *current_field { // Highlight within the same field
|
// Determine the actual start and end fields/chars for rendering
|
||||||
let start = anchor_char.min(current_cursor_pos);
|
let start_field = min(anchor_field, *current_field_idx);
|
||||||
let end = anchor_char.max(current_cursor_pos);
|
let end_field = max(anchor_field, *current_field_idx);
|
||||||
let text = input.as_str();
|
|
||||||
let len = text.chars().count();
|
|
||||||
|
|
||||||
// Ensure start and end are within bounds
|
let (start_char, end_char) = if anchor_field == *current_field_idx {
|
||||||
let safe_start = start.min(len);
|
// Single line selection
|
||||||
let safe_end = end.min(len);
|
(min(anchor_char, current_cursor_pos), max(anchor_char, current_cursor_pos))
|
||||||
|
} else if anchor_field < *current_field_idx {
|
||||||
|
// Anchor is above cursor
|
||||||
|
(anchor_char, current_cursor_pos)
|
||||||
|
} else {
|
||||||
|
// Anchor is below cursor
|
||||||
|
(current_cursor_pos, anchor_char)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Style for highlighted text
|
||||||
|
let highlight_style = Style::default().fg(theme.highlight).bg(theme.highlight_bg).add_modifier(Modifier::BOLD);
|
||||||
|
// Style for normal text within the highlight range (active field color)
|
||||||
|
let normal_style_in_highlight = Style::default().fg(theme.highlight);
|
||||||
|
// Style for normal text outside highlight range (inactive field color)
|
||||||
|
let normal_style_outside = Style::default().fg(theme.fg);
|
||||||
|
|
||||||
|
if i >= start_field && i <= end_field {
|
||||||
|
// This line is within the 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 before: String = text.chars().take(safe_start).collect();
|
||||||
let highlighted: String = text.chars().skip(safe_start).take(safe_end - 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();
|
let after: String = text.chars().skip(safe_end).collect();
|
||||||
|
line = Line::from(vec![
|
||||||
Line::from(vec![
|
Span::styled(before, normal_style_in_highlight),
|
||||||
Span::styled(before, Style::default().fg(theme.fg)),
|
Span::styled(highlighted, highlight_style),
|
||||||
Span::styled(
|
Span::styled(after, normal_style_in_highlight),
|
||||||
highlighted,
|
]);
|
||||||
Style::default().fg(theme.highlight).bg(theme.highlight_bg).add_modifier(Modifier::BOLD)
|
} else if i == start_field { // Case 2: Multi-Line Highlight - Start Line
|
||||||
),
|
let safe_start = start_char.min(text_len);
|
||||||
Span::styled(after, Style::default().fg(theme.fg)),
|
let before: String = text.chars().take(safe_start).collect();
|
||||||
])
|
let highlighted: String = text.chars().skip(safe_start).collect();
|
||||||
} else {
|
line = Line::from(vec![
|
||||||
// Field is not the anchor or not the current field during highlight
|
Span::styled(before, normal_style_in_highlight), // Use active color before highlight starts
|
||||||
// Render normally for now (could extend to multi-line later)
|
Span::styled(highlighted, highlight_style),
|
||||||
Line::from(Span::styled(input.as_str(), Style::default().fg(theme.fg)))
|
]);
|
||||||
|
} 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();
|
||||||
|
line = Line::from(vec![
|
||||||
|
Span::styled(highlighted, highlight_style),
|
||||||
|
Span::styled(after, normal_style_in_highlight), // Use active color after highlight ends
|
||||||
|
]);
|
||||||
|
} else { // Case 3: Multi-Line Highlight - Middle Line
|
||||||
|
line = Line::from(Span::styled(text, highlight_style)); // Highlight whole line
|
||||||
|
}
|
||||||
|
} else { // Case 5: Line Outside Highlight Range
|
||||||
|
line = Line::from(Span::styled(
|
||||||
|
text,
|
||||||
|
if is_active { normal_style_in_highlight } else { normal_style_outside }
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not in highlight mode, render normally
|
// Not in highlight mode, render normally
|
||||||
Line::from(Span::styled(
|
line = Line::from(Span::styled(
|
||||||
input.as_str(),
|
text,
|
||||||
if is_active { Style::default().fg(theme.highlight) } else { Style::default().fg(theme.fg) }
|
if is_active { Style::default().fg(theme.highlight) } else { Style::default().fg(theme.fg) }
|
||||||
))
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
let input_display = Paragraph::new(line)
|
let input_display = Paragraph::new(line)
|
||||||
@@ -123,8 +162,8 @@ pub fn render_canvas(
|
|||||||
|
|
||||||
if is_active {
|
if is_active {
|
||||||
active_field_input_rect = Some(input_rows[i]);
|
active_field_input_rect = Some(input_rows[i]);
|
||||||
// Cursor position calculation remains the same
|
// Set cursor position (using current_field_idx directly)
|
||||||
let cursor_x = input_rows[i].x + current_cursor_pos as u16;
|
let cursor_x = input_rows[i].x + form_state.current_cursor_pos() as u16;
|
||||||
let cursor_y = input_rows[i].y;
|
let cursor_y = input_rows[i].y;
|
||||||
f.set_cursor_position((cursor_x, cursor_y));
|
f.set_cursor_position((cursor_x, cursor_y));
|
||||||
}
|
}
|
||||||
@@ -132,3 +171,4 @@ pub fn render_canvas(
|
|||||||
|
|
||||||
active_field_input_rect
|
active_field_input_rect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user