mirror of
https://github.com/ChrisTitusTech/linutil.git
synced 2024-11-22 05:12:27 +00:00
Merge pull request #108 from afonsofrancof/cleanup
Fixed the wrong command on selection bug in search.
This commit is contained in:
commit
51e992375b
99
src/list.rs
99
src/list.rs
|
@ -129,9 +129,7 @@ impl CustomList {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw our custom widget to the frame
|
/// Draw our custom widget to the frame
|
||||||
pub fn draw(&mut self, frame: &mut Frame, area: Rect, filter: String, state: &AppState) {
|
pub fn draw(&mut self, frame: &mut Frame, area: Rect, state: &AppState) {
|
||||||
self.filter(filter);
|
|
||||||
|
|
||||||
let item_list: Vec<Line> = if self.filter_query.is_empty() {
|
let item_list: Vec<Line> = if self.filter_query.is_empty() {
|
||||||
let mut items: Vec<Line> = vec![];
|
let mut items: Vec<Line> = vec![];
|
||||||
// If we are not at the root of our filesystem tree, we need to add `..` path, to be able
|
// If we are not at the root of our filesystem tree, we need to add `..` path, to be able
|
||||||
|
@ -168,9 +166,7 @@ impl CustomList {
|
||||||
}
|
}
|
||||||
items
|
items
|
||||||
} else {
|
} else {
|
||||||
let mut sorted_items = self.filtered_items.clone();
|
self.filtered_items
|
||||||
sorted_items.sort_by(|a, b| a.name.cmp(b.name));
|
|
||||||
sorted_items
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|node| {
|
.map(|node| {
|
||||||
Line::from(format!("{} {}", state.theme.cmd_icon, node.name))
|
Line::from(format!("{} {}", state.theme.cmd_icon, node.name))
|
||||||
|
@ -225,6 +221,7 @@ impl CustomList {
|
||||||
self.filtered_items.clear();
|
self.filtered_items.clear();
|
||||||
|
|
||||||
let query_lower = query.to_lowercase();
|
let query_lower = query.to_lowercase();
|
||||||
|
|
||||||
let mut stack = vec![self.inner_tree.root().id()];
|
let mut stack = vec![self.inner_tree.root().id()];
|
||||||
|
|
||||||
while let Some(node_id) = stack.pop() {
|
while let Some(node_id) = stack.pop() {
|
||||||
|
@ -238,6 +235,7 @@ impl CustomList {
|
||||||
stack.push(child.id());
|
stack.push(child.id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.filtered_items.sort_by(|a, b| a.name.cmp(b.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resets the selection to the first item
|
/// Resets the selection to the first item
|
||||||
|
@ -264,7 +262,7 @@ impl CustomList {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.try_scroll_down();
|
self.list_state.select_next();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
KeyCode::Char('k') | KeyCode::Up => {
|
KeyCode::Char('k') | KeyCode::Up => {
|
||||||
|
@ -275,7 +273,7 @@ impl CustomList {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.try_scroll_up();
|
self.list_state.select_previous();
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
// The 'p' key toggles the preview on and off
|
// The 'p' key toggles the preview on and off
|
||||||
|
@ -284,7 +282,7 @@ impl CustomList {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyCode::Enter => {
|
KeyCode::Enter => {
|
||||||
if self.preview_window_state.is_none() {
|
if self.preview_window_state.is_none() {
|
||||||
self.handle_enter()
|
self.handle_enter()
|
||||||
} else {
|
} else {
|
||||||
|
@ -327,38 +325,6 @@ impl CustomList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_scroll_up(&mut self) {
|
|
||||||
if let Some(selected) = self.list_state.selected() {
|
|
||||||
if selected > 0 {
|
|
||||||
self.list_state.select(Some(selected.saturating_sub(1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_scroll_down(&mut self) {
|
|
||||||
let count = if self.filter_query.is_empty() {
|
|
||||||
let curr = self
|
|
||||||
.inner_tree
|
|
||||||
.get(*self.visit_stack.last().unwrap())
|
|
||||||
.unwrap();
|
|
||||||
curr.children().count()
|
|
||||||
} else {
|
|
||||||
self.filtered_items.len()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(curr_selection) = self.list_state.selected() {
|
|
||||||
if self.at_root() {
|
|
||||||
self.list_state
|
|
||||||
.select(Some((curr_selection + 1).min(count - 1)));
|
|
||||||
} else {
|
|
||||||
// When we are not at the root, we have to account for 1 more "virtual" node, `..`. So
|
|
||||||
// the count is 1 bigger (select is 0 based, because it's an index)
|
|
||||||
self.list_state
|
|
||||||
.select(Some((curr_selection + 1).min(count)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Scroll the preview window down
|
/// Scroll the preview window down
|
||||||
fn scroll_preview_window_down(&mut self) {
|
fn scroll_preview_window_down(&mut self) {
|
||||||
if let Some(pw_state) = &mut self.preview_window_state {
|
if let Some(pw_state) = &mut self.preview_window_state {
|
||||||
|
@ -383,7 +349,8 @@ impl CustomList {
|
||||||
/// This could probably be integrated into the 'handle_enter()' method to avoid code
|
/// This could probably be integrated into the 'handle_enter()' method to avoid code
|
||||||
/// duplication, but I don't want to make too major changes to the codebase.
|
/// duplication, but I don't want to make too major changes to the codebase.
|
||||||
fn get_selected_command(&self) -> Option<Command> {
|
fn get_selected_command(&self) -> Option<Command> {
|
||||||
let selected = self.list_state.selected().unwrap();
|
let selected_index = self.list_state.selected().unwrap_or(0);
|
||||||
|
println!("Selected Index: {}", selected_index);
|
||||||
|
|
||||||
if self.filter_query.is_empty() {
|
if self.filter_query.is_empty() {
|
||||||
// No filter query, use the regular tree navigation
|
// No filter query, use the regular tree navigation
|
||||||
|
@ -392,25 +359,28 @@ impl CustomList {
|
||||||
.get(*self.visit_stack.last().unwrap())
|
.get(*self.visit_stack.last().unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// If we are not at the root and the first item is selected, it's the `..` item
|
if !self.at_root() && selected_index == 0 {
|
||||||
if !self.at_root() && selected == 0 {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (mut idx, node) in curr.children().enumerate() {
|
let mut actual_index = selected_index;
|
||||||
if !self.at_root() {
|
if !self.at_root() {
|
||||||
idx += 1;
|
actual_index -= 1; // Adjust for the ".." item if not at root
|
||||||
}
|
}
|
||||||
if idx == selected {
|
|
||||||
|
for (idx, node) in curr.children().enumerate() {
|
||||||
|
if idx == actual_index {
|
||||||
return Some(node.value().command.clone());
|
return Some(node.value().command.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Filter query is active, use the filtered items
|
// Filter query is active, use the filtered items
|
||||||
if let Some(filtered_node) = self.filtered_items.get(selected) {
|
if let Some(filtered_node) = self.filtered_items.get(selected_index) {
|
||||||
|
println!("Filtered Node Name: {}", filtered_node.name);
|
||||||
return Some(filtered_node.command.clone());
|
return Some(filtered_node.command.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,13 +391,7 @@ impl CustomList {
|
||||||
///
|
///
|
||||||
/// Returns `Some(command)` when command is selected, othervise we returns `None`
|
/// Returns `Some(command)` when command is selected, othervise we returns `None`
|
||||||
fn handle_enter(&mut self) -> Option<Command> {
|
fn handle_enter(&mut self) -> Option<Command> {
|
||||||
// Ensure an item is selected if none is selected
|
let selected_index = self.list_state.selected().unwrap_or(0);
|
||||||
if self.list_state.selected().is_none() {
|
|
||||||
self.list_state.select(Some(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the selected index
|
|
||||||
let selected = self.list_state.selected().unwrap();
|
|
||||||
|
|
||||||
if self.filter_query.is_empty() {
|
if self.filter_query.is_empty() {
|
||||||
// No filter query, use the regular tree navigation
|
// No filter query, use the regular tree navigation
|
||||||
|
@ -436,21 +400,19 @@ impl CustomList {
|
||||||
.get(*self.visit_stack.last().unwrap())
|
.get(*self.visit_stack.last().unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// if we are not at the root, and the first element is selected,
|
if !self.at_root() && selected_index == 0 {
|
||||||
// we can be sure it's '..', so we go up the directory
|
|
||||||
if !self.at_root() && selected == 0 {
|
|
||||||
self.visit_stack.pop();
|
self.visit_stack.pop();
|
||||||
self.list_state.select(Some(0));
|
self.list_state.select(Some(0));
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (mut idx, node) in curr.children().enumerate() {
|
let mut actual_index = selected_index;
|
||||||
// at this point, we know that we are not on the .. item, and our indexes of the items never had ..
|
if !self.at_root() {
|
||||||
// item. so to balance it out, in case the selection index contains .., se add 1 to our node index
|
actual_index -= 1; // Adjust for the ".." item if not at root
|
||||||
if !self.at_root() {
|
}
|
||||||
idx += 1;
|
|
||||||
}
|
for (idx, node) in curr.children().enumerate() {
|
||||||
if idx == selected {
|
if idx == actual_index {
|
||||||
if node.has_children() {
|
if node.has_children() {
|
||||||
self.visit_stack.push(node.id());
|
self.visit_stack.push(node.id());
|
||||||
self.list_state.select(Some(0));
|
self.list_state.select(Some(0));
|
||||||
|
@ -462,10 +424,11 @@ impl CustomList {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Filter query is active, use the filtered items
|
// Filter query is active, use the filtered items
|
||||||
if let Some(filtered_node) = self.filtered_items.get(selected) {
|
if let Some(filtered_node) = self.filtered_items.get(selected_index) {
|
||||||
return Some(filtered_node.command.clone());
|
return Some(filtered_node.command.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ fn run<B: Backend>(terminal: &mut Terminal<B>, state: &AppState) -> io::Result<(
|
||||||
//Render the search bar (First chunk of the screen)
|
//Render the search bar (First chunk of the screen)
|
||||||
frame.render_widget(search_bar, chunks[0]);
|
frame.render_widget(search_bar, chunks[0]);
|
||||||
//Render the command list (Second chunk of the screen)
|
//Render the command list (Second chunk of the screen)
|
||||||
custom_list.draw(frame, chunks[1], search_input.clone(), state);
|
custom_list.draw(frame, chunks[1], state);
|
||||||
|
|
||||||
if let Some(ref mut command) = &mut command_opt {
|
if let Some(ref mut command) = &mut command_opt {
|
||||||
command.draw(frame, state);
|
command.draw(frame, state);
|
||||||
|
@ -154,12 +154,17 @@ fn run<B: Backend>(terminal: &mut Terminal<B>, state: &AppState) -> io::Result<(
|
||||||
//Insert user input into the search bar
|
//Insert user input into the search bar
|
||||||
if in_search_mode {
|
if in_search_mode {
|
||||||
match key.code {
|
match key.code {
|
||||||
KeyCode::Char(c) => search_input.push(c),
|
KeyCode::Char(c) => {
|
||||||
|
search_input.push(c);
|
||||||
|
custom_list.filter(search_input.clone());
|
||||||
|
}
|
||||||
KeyCode::Backspace => {
|
KeyCode::Backspace => {
|
||||||
search_input.pop();
|
search_input.pop();
|
||||||
|
custom_list.filter(search_input.clone());
|
||||||
}
|
}
|
||||||
KeyCode::Esc => {
|
KeyCode::Esc => {
|
||||||
search_input = String::new();
|
search_input = String::new();
|
||||||
|
custom_list.filter(search_input.clone());
|
||||||
in_search_mode = false
|
in_search_mode = false
|
||||||
}
|
}
|
||||||
KeyCode::Enter => {
|
KeyCode::Enter => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user