diff options
author | qkzk <qu3nt1n@gmail.com> | 2023-11-09 21:49:35 +0100 |
---|---|---|
committer | qkzk <qu3nt1n@gmail.com> | 2023-11-09 21:49:35 +0100 |
commit | 77dc7c93cc17b68e87c02e9d4ea3c164f2bd6780 (patch) | |
tree | 995d35a43919de89c3dad2abd8713a52ec45218f | |
parent | 9b847e37543f4e610fe238ff90a23799287e84c8 (diff) |
improve search in tree. Far from perfect
-rw-r--r-- | development.md | 3 | ||||
-rw-r--r-- | src/event_exec.rs | 18 | ||||
-rw-r--r-- | src/tree.rs | 39 |
3 files changed, 32 insertions, 28 deletions
diff --git a/development.md b/development.md index 1b324172..3a74d9a3 100644 --- a/development.md +++ b/development.md @@ -618,6 +618,8 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally. - [x] FIX: enter a dir from normal mode shouldn't set mode tree - [x] Use a generic trait for movements - [x] FIX: first line position for tree + - [x] FIX: searching for file very low don't scroll there + - [x] FIX: search can only find the first match - [ ] test everything - [ ] refactor - [x] document @@ -625,7 +627,6 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally. ## TODO - [ ] FIX: tab.selected() should return Option<&FileInfo> -- [ ] FIX: search can only find the first match - [ ] use widget for every drawable element. First line should be a collection of widget which are drawned - [ ] while second window is opened, if the selection is below half screen, it's not shown anymore. Scroll to second element if needed diff --git a/src/event_exec.rs b/src/event_exec.rs index 5514ccf1..4ca457e0 100644 --- a/src/event_exec.rs +++ b/src/event_exec.rs @@ -471,12 +471,12 @@ impl EventAction { pub fn search_next(status: &mut Status) -> Result<()> { let tab = status.selected(); + let Some(searched) = tab.searched.clone() else { + return Ok(()); + }; match tab.mode { - Mode::Tree => (), + Mode::Tree => tab.tree.search_first_match(&searched), _ => { - let Some(searched) = tab.searched.clone() else { - return Ok(()); - }; let next_index = (tab.path_content.index + 1) % tab.path_content.content.len(); tab.search_from(&searched, next_index); status.update_second_pane_for_preview()?; @@ -1381,16 +1381,8 @@ impl LeaveMode { tab.searched = Some(searched.clone()); match tab.previous_mode { Mode::Tree => { + log::info!("searching in tree"); tab.tree.search_first_match(searched); - // tab.directory.tree.unselect_children(); - // if let Some(position) = tab.directory.tree.select_first_match(&searched) { - // tab.directory.tree.position = position; - // (_, _, tab.directory.tree.current_node) = - // tab.directory.tree.select_from_position()?; - // } else { - // tab.directory.tree.select_root() - // }; - // tab.directory.make_preview(); } _ => { let next_index = tab.path_content.index; diff --git a/src/tree.rs b/src/tree.rs index e78592fc..b00c37ae 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -416,6 +416,9 @@ impl Tree { } fn select_path(&mut self, clicked_path: &Path) { + if clicked_path == self.selected { + return; + } let Some(new_node) = self.nodes.get_mut(clicked_path) else { return; }; @@ -469,24 +472,25 @@ impl Tree { } } - // FIX: can only find the first match and nothing else /// Select the first node whose filename match a pattern. pub fn search_first_match(&mut self, pattern: &str) { - let initial_selected = self.selected.to_owned(); - let Some((found_path, found_node)) = self.nodes.iter_mut().find(|(path, _)| { - path.file_name() - .unwrap_or_default() - .to_string_lossy() - .contains(pattern) - }) else { - return; + let Some(current_index) = self.nodes.keys().position(|path| path == &self.selected) else { + unreachable!("selected should be in pos"); }; - self.selected = found_path.to_owned(); - found_node.select(); - let Some(current_node) = self.nodes.get_mut(&initial_selected) else { - unreachable!("selected path should be in nodes"); + if let Some(found_path) = self + .nodes + .keys() + .skip(current_index + 1) + .find(|path| path_filename_contains(path, pattern)) + { + self.go(To::Path(found_path.to_owned().as_path())); + } else if let Some(found_path) = self + .nodes + .keys() + .find(|path| path_filename_contains(path, pattern)) + { + self.go(To::Path(found_path.to_owned().as_path())); }; - current_node.unselect(); } /// Returns a navigable vector of `ColoredTriplet` and the index of selected file @@ -613,3 +617,10 @@ pub fn calculate_top_bottom(selected_index: usize, terminal_height: usize) -> (u (top, bottom) } + +fn path_filename_contains(path: &Path, pattern: &str) -> bool { + path.file_name() + .unwrap_or_default() + .to_string_lossy() + .contains(pattern) +} |