From edae301047c0555781a4da50e6b42dbf092ee70e Mon Sep 17 00:00:00 2001 From: nyx Date: Tue, 1 Oct 2024 23:09:30 -0400 Subject: [PATCH 1/5] return user to their previous position if they enter a subdir --- tui/src/state.rs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/tui/src/state.rs b/tui/src/state.rs index ce724868..0771681d 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -60,6 +60,7 @@ pub struct AppState { drawable: bool, #[cfg(feature = "tips")] tip: &'static str, + position_stack: Vec, } pub enum Focus { @@ -94,6 +95,7 @@ impl AppState { drawable: false, #[cfg(feature = "tips")] tip: get_random_tip(), + position_stack: vec![0], }; state.update_items(); @@ -572,9 +574,12 @@ impl AppState { } fn enter_parent_directory(&mut self) { - self.visit_stack.pop(); - self.selection.select(Some(0)); - self.update_items(); + if self.visit_stack.len() > 1 { + self.visit_stack.pop(); + let previous_position = self.position_stack.pop().unwrap_or(0); + self.selection.select(Some(previous_position)); + self.update_items(); + } } fn get_selected_node(&self) -> Option> { @@ -601,20 +606,19 @@ impl AppState { } pub fn go_to_selected_dir(&mut self) { - let mut selected_index = self.selection.selected().unwrap_or(0); + let selected_index = self.selection.selected().unwrap_or(0); if !self.at_root() && selected_index == 0 { self.enter_parent_directory(); return; } - if !self.at_root() { - selected_index = selected_index.saturating_sub(1); - } + let actual_index = if self.at_root() { selected_index } else { selected_index - 1 }; - if let Some(item) = self.filter.item_list().get(selected_index) { + if let Some(item) = self.filter.item_list().get(actual_index) { if item.has_children { self.visit_stack.push(item.id); + self.position_stack.push(selected_index); self.selection.select(Some(0)); self.update_items(); } @@ -646,7 +650,6 @@ impl AppState { pub fn selected_item_is_up_dir(&self) -> bool { let selected_index = self.selection.selected().unwrap_or(0); - !self.at_root() && selected_index == 0 } @@ -668,7 +671,11 @@ impl AppState { } fn handle_enter(&mut self) { - if self.selected_item_is_cmd() { + if self.selected_item_is_up_dir() { + self.enter_parent_directory(); + } else if self.selected_item_is_dir() { + self.go_to_selected_dir(); + } else if self.selected_item_is_cmd() { if self.selected_commands.is_empty() { if let Some(node) = self.get_selected_node() { self.selected_commands.push(node); @@ -683,8 +690,6 @@ impl AppState { let prompt = ConfirmPrompt::new(&cmd_names[..]); self.focus = Focus::ConfirmationPrompt(Float::new(Box::new(prompt), 40, 40)); - } else { - self.go_to_selected_dir(); } } From 006186859739e727126ac5af3d840b68ef6a1f5f Mon Sep 17 00:00:00 2001 From: nyx Date: Tue, 1 Oct 2024 23:28:23 -0400 Subject: [PATCH 2/5] fix lint --- tui/src/state.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tui/src/state.rs b/tui/src/state.rs index 0771681d..e132ee15 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -613,7 +613,11 @@ impl AppState { return; } - let actual_index = if self.at_root() { selected_index } else { selected_index - 1 }; + let actual_index = if self.at_root() { + selected_index + } else { + selected_index - 1 + }; if let Some(item) = self.filter.item_list().get(actual_index) { if item.has_children { From 92643de3ad1e86ca841857bbe8e0b9a215b9ae37 Mon Sep 17 00:00:00 2001 From: nyx Date: Wed, 2 Oct 2024 00:02:14 -0400 Subject: [PATCH 3/5] implement changes proposed by adam Co-authored-by: Adam Perkowski --- tui/src/state.rs | 55 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/tui/src/state.rs b/tui/src/state.rs index e132ee15..a5218f70 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -77,6 +77,13 @@ pub struct ListEntry { pub has_children: bool, } +enum SelectedItem { + UpDir, + Directory, + Command, + None, +} + impl AppState { pub fn new(theme: Theme, override_validation: bool) -> Self { let tabs = linutil_core::get_tabs(!override_validation); @@ -574,9 +581,8 @@ impl AppState { } fn enter_parent_directory(&mut self) { - if self.visit_stack.len() > 1 { + if let Some(previous_position) = self.position_stack.pop() { self.visit_stack.pop(); - let previous_position = self.position_stack.pop().unwrap_or(0); self.selection.select(Some(previous_position)); self.update_items(); } @@ -674,26 +680,39 @@ impl AppState { } } - fn handle_enter(&mut self) { + fn get_selected_item_type(&self) -> SelectedItem { if self.selected_item_is_up_dir() { - self.enter_parent_directory(); + SelectedItem::UpDir } else if self.selected_item_is_dir() { - self.go_to_selected_dir(); + SelectedItem::Directory } else if self.selected_item_is_cmd() { - if self.selected_commands.is_empty() { - if let Some(node) = self.get_selected_node() { - self.selected_commands.push(node); + SelectedItem::Command + } else { + SelectedItem::None + } + } + + fn handle_enter(&mut self) { + match self.get_selected_item_type() { + SelectedItem::UpDir => self.enter_parent_directory(), + SelectedItem::Directory => self.go_to_selected_dir(), + SelectedItem::Command => { + if self.selected_commands.is_empty() { + if let Some(node) = self.get_selected_node() { + self.selected_commands.push(node); + } } + + let cmd_names = self + .selected_commands + .iter() + .map(|node| node.name.as_str()) + .collect::>(); + + let prompt = ConfirmPrompt::new(&cmd_names[..]); + self.focus = Focus::ConfirmationPrompt(Float::new(Box::new(prompt), 40, 40)); } - - let cmd_names = self - .selected_commands - .iter() - .map(|node| node.name.as_str()) - .collect::>(); - - let prompt = ConfirmPrompt::new(&cmd_names[..]); - self.focus = Focus::ConfirmationPrompt(Float::new(Box::new(prompt), 40, 40)); + SelectedItem::None => {} } } @@ -757,4 +776,4 @@ fn get_random_tip() -> &'static str { let mut rng = rand::thread_rng(); let random_index = rng.gen_range(0..tips.len()); tips[random_index] -} +} \ No newline at end of file From 70d3abfca44cbe44c806be59b5213423d72d5b19 Mon Sep 17 00:00:00 2001 From: nyx Date: Wed, 2 Oct 2024 00:27:01 -0400 Subject: [PATCH 4/5] add newline back --- tui/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tui/src/state.rs b/tui/src/state.rs index a5218f70..d8e77bad 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -776,4 +776,4 @@ fn get_random_tip() -> &'static str { let mut rng = rand::thread_rng(); let random_index = rng.gen_range(0..tips.len()); tips[random_index] -} \ No newline at end of file +} From 6d1f3a0cef2d6b61aaab990b5bcb5d2178d45e4b Mon Sep 17 00:00:00 2001 From: cartercanedy <99052281+cartercanedy@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:40:01 -0700 Subject: [PATCH 5/5] coalesce `visit_stack` and `position_stack` (#6) --- tui/src/state.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/tui/src/state.rs b/tui/src/state.rs index d8e77bad..02f738af 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -50,7 +50,7 @@ pub struct AppState { current_tab: ListState, /// This stack keeps track of our "current directory". You can think of it as `pwd`. but not /// just the current directory, all paths that took us here, so we can "cd .." - visit_stack: Vec, + visit_stack: Vec<(NodeId, usize)>, /// This is the state asociated with the list widget, used to display the selection in the /// widget selection: ListState, @@ -60,7 +60,6 @@ pub struct AppState { drawable: bool, #[cfg(feature = "tips")] tip: &'static str, - position_stack: Vec, } pub enum Focus { @@ -94,7 +93,7 @@ impl AppState { focus: Focus::List, tabs, current_tab: ListState::default().with_selected(Some(0)), - visit_stack: vec![root_id], + visit_stack: vec![(root_id, 0usize)], selection: ListState::default().with_selected(Some(0)), filter: Filter::new(), multi_select: false, @@ -102,7 +101,6 @@ impl AppState { drawable: false, #[cfg(feature = "tips")] tip: get_random_tip(), - position_stack: vec![0], }; state.update_items(); @@ -557,7 +555,7 @@ impl AppState { self.filter.update_items( &self.tabs, self.current_tab.selected().unwrap(), - *self.visit_stack.last().unwrap(), + self.visit_stack.last().unwrap().0, ); if !self.is_current_tab_multi_selectable() { self.multi_select = false; @@ -581,8 +579,7 @@ impl AppState { } fn enter_parent_directory(&mut self) { - if let Some(previous_position) = self.position_stack.pop() { - self.visit_stack.pop(); + if let Some((_, previous_position)) = self.visit_stack.pop() { self.selection.select(Some(previous_position)); self.update_items(); } @@ -627,8 +624,7 @@ impl AppState { if let Some(item) = self.filter.item_list().get(actual_index) { if item.has_children { - self.visit_stack.push(item.id); - self.position_stack.push(selected_index); + self.visit_stack.push((item.id, selected_index)); self.selection.select(Some(0)); self.update_items(); } @@ -746,10 +742,13 @@ impl AppState { } fn refresh_tab(&mut self) { - self.visit_stack = vec![self.tabs[self.current_tab.selected().unwrap()] - .tree - .root() - .id()]; + self.visit_stack = vec![( + self.tabs[self.current_tab.selected().unwrap()] + .tree + .root() + .id(), + 0usize, + )]; self.selection.select(Some(0)); self.update_items(); }