it works amazingly well now, we can select the table name via command line

This commit is contained in:
filipriec
2025-05-30 22:46:32 +02:00
parent b0c865ab76
commit ff74e1aaa1
4 changed files with 387 additions and 140 deletions

View File

@@ -1,6 +1,7 @@
// src/components/common/find_file_palette.rs
use crate::config::colors::themes::Theme;
use crate::modes::general::command_navigation::NavigationState; // Corrected path
use ratatui::{
layout::{Constraint, Direction, Layout, Rect},
style::Style,
@@ -9,21 +10,19 @@ use ratatui::{
};
use unicode_width::UnicodeWidthStr;
// Define a fixed height for the options list in the command palette
const PALETTE_MAX_VISIBLE_OPTIONS: usize = 15;
// Use a regular space character for padding.
const PADDING_CHAR: &str = " ";
pub fn render_find_file_palette(
f: &mut Frame,
area: Rect,
theme: &Theme,
palette_input: &str, // Specific input for the palette
options: &[String], // These are already filtered options
selected_index: Option<usize>, // Index within the filtered `options`
navigation_state: &NavigationState,
) {
let num_total_filtered = options.len();
let current_selected_list_idx = selected_index;
let palette_display_input = navigation_state.get_display_input(); // Use the new method
let num_total_filtered = navigation_state.filtered_options.len();
let current_selected_list_idx = navigation_state.selected_index;
let mut display_start_offset = 0;
if num_total_filtered > PALETTE_MAX_VISIBLE_OPTIONS {
@@ -39,34 +38,53 @@ pub fn render_find_file_palette(
}
display_start_offset = display_start_offset.max(0);
let display_end_offset =
(display_start_offset + PALETTE_MAX_VISIBLE_OPTIONS).min(num_total_filtered);
let display_end_offset = (display_start_offset + PALETTE_MAX_VISIBLE_OPTIONS)
.min(num_total_filtered);
let visible_options_slice = if num_total_filtered > 0 {
&options[display_start_offset..display_end_offset]
// navigation_state.filtered_options is Vec<(usize, String)>
// We only need the String part for display.
let visible_options_slice: Vec<&String> = if num_total_filtered > 0 {
navigation_state.filtered_options
[display_start_offset..display_end_offset]
.iter()
.map(|(_, opt_str)| opt_str)
.collect()
} else {
&[]
Vec::new()
};
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(1), // For palette input line
Constraint::Length(PALETTE_MAX_VISIBLE_OPTIONS as u16), // For options list (fixed height)
Constraint::Min(0), // For options list, take remaining space
])
.split(area);
// Ensure list_area height does not exceed PALETTE_MAX_VISIBLE_OPTIONS
let list_area_height = std::cmp::min(chunks[1].height, PALETTE_MAX_VISIBLE_OPTIONS as u16);
let final_list_area = Rect::new(chunks[1].x, chunks[1].y, chunks[1].width, list_area_height);
let input_area = chunks[0];
let list_area = chunks[1];
// let list_area = chunks[1]; // Use final_list_area
// Draw the palette input line (with padding)
let base_prompt_text = format!("Find File: {}", palette_input);
let prompt_prefix = match navigation_state.navigation_type {
crate::modes::general::command_navigation::NavigationType::FindFile => "Find File: ",
crate::modes::general::command_navigation::NavigationType::TableTree => "Table Path: ",
};
let base_prompt_text = format!("{}{}", prompt_prefix, palette_display_input);
let prompt_text_width = UnicodeWidthStr::width(base_prompt_text.as_str());
let input_area_width = input_area.width as usize;
let input_padding_needed = input_area_width.saturating_sub(prompt_text_width);
let input_padding_needed =
input_area_width.saturating_sub(prompt_text_width);
let padded_prompt_text = if input_padding_needed > 0 {
format!("{}{}", base_prompt_text, PADDING_CHAR.repeat(input_padding_needed))
format!(
"{}{}",
base_prompt_text,
PADDING_CHAR.repeat(input_padding_needed)
)
} else {
base_prompt_text
};
@@ -75,12 +93,17 @@ pub fn render_find_file_palette(
.style(Style::default().fg(theme.accent).bg(theme.bg));
f.render_widget(input_paragraph, input_area);
// --- Draw the list of options, ensuring all PALETTE_MAX_VISIBLE_OPTIONS rows are covered ---
let mut display_list_items: Vec<ListItem> = Vec::with_capacity(PALETTE_MAX_VISIBLE_OPTIONS);
let mut display_list_items: Vec<ListItem> =
Vec::with_capacity(PALETTE_MAX_VISIBLE_OPTIONS);
for (idx_in_slice, opt_str) in visible_options_slice.iter().enumerate() {
let original_list_idx = display_start_offset + idx_in_slice;
let is_selected = current_selected_list_idx == Some(original_list_idx);
for (idx_in_visible_slice, opt_str) in
visible_options_slice.iter().enumerate()
{
// The selected_index in navigation_state is relative to the full filtered_options list.
// We need to check if the current item (from the visible slice) corresponds to the selected_index.
let original_filtered_idx = display_start_offset + idx_in_visible_slice;
let is_selected =
current_selected_list_idx == Some(original_filtered_idx);
let style = if is_selected {
Style::default().fg(theme.bg).bg(theme.accent)
@@ -89,7 +112,7 @@ pub fn render_find_file_palette(
};
let opt_width = opt_str.width() as u16;
let list_item_width = list_area.width;
let list_item_width = final_list_area.width;
let padding_amount = list_item_width.saturating_sub(opt_width);
let padded_opt_str = format!(
"{}{}",
@@ -99,10 +122,12 @@ pub fn render_find_file_palette(
display_list_items.push(ListItem::new(padded_opt_str).style(style));
}
// Fill remaining lines in the list area to maintain fixed height appearance
let num_rendered_options = display_list_items.len();
if num_rendered_options < PALETTE_MAX_VISIBLE_OPTIONS {
for _ in num_rendered_options..PALETTE_MAX_VISIBLE_OPTIONS {
let empty_padded_str = PADDING_CHAR.repeat(list_area.width as usize);
if num_rendered_options < PALETTE_MAX_VISIBLE_OPTIONS && (final_list_area.height as usize) > num_rendered_options {
for _ in num_rendered_options..(final_list_area.height as usize) {
let empty_padded_str =
PADDING_CHAR.repeat(final_list_area.width as usize);
display_list_items.push(
ListItem::new(empty_padded_str)
.style(Style::default().fg(theme.bg).bg(theme.bg)),
@@ -110,7 +135,8 @@ pub fn render_find_file_palette(
}
}
let options_list_widget = List::new(display_list_items)
.block(Block::default().style(Style::default().bg(theme.bg)));
f.render_widget(options_list_widget, list_area);
f.render_widget(options_list_widget, final_list_area);
}