summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2023-11-09 21:49:35 +0100
committerqkzk <qu3nt1n@gmail.com>2023-11-09 21:49:35 +0100
commit77dc7c93cc17b68e87c02e9d4ea3c164f2bd6780 (patch)
tree995d35a43919de89c3dad2abd8713a52ec45218f
parent9b847e37543f4e610fe238ff90a23799287e84c8 (diff)
improve search in tree. Far from perfect
-rw-r--r--development.md3
-rw-r--r--src/event_exec.rs18
-rw-r--r--src/tree.rs39
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)
+}