From ef73559a8e0a9ad222ed1e459ddbd5bb505e32ca Mon Sep 17 00:00:00 2001 From: wongjiahau Date: Wed, 15 Feb 2023 09:58:54 +0800 Subject: [PATCH] fix(explore): cannot focus explorer if no opened document --- helix-term/src/commands.rs | 4 +- helix-term/src/ui/explore.rs | 3 +- helix-term/src/ui/tree.rs | 194 +++++------------------------------ 3 files changed, 26 insertions(+), 175 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index d0776822..102940f7 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2241,9 +2241,7 @@ fn reveal_current_file(cx: &mut Context) { None => { editor.explorer = Some(overlayed(ui::Explorer::new(cx)?)); let explorer = editor.explorer.as_mut().unwrap(); - explorer.content.focus(); - explorer.content.reveal_current_file(cx)?; - Ok(()) + explorer.content.reveal_current_file(cx) } })() .unwrap_or_else(|err| { diff --git a/helix-term/src/ui/explore.rs b/helix-term/src/ui/explore.rs index 96a064bf..a442f023 100644 --- a/helix-term/src/ui/explore.rs +++ b/helix-term/src/ui/explore.rs @@ -233,11 +233,11 @@ impl Explorer { .split(std::path::MAIN_SEPARATOR) .collect::>(); self.tree.reveal_item(segments, &self.state.filter)?; - self.focus(); Ok(()) } pub fn reveal_current_file(&mut self, cx: &mut Context) -> Result<()> { + self.focus(); let current_document_path = doc!(cx.editor).path().cloned(); match current_document_path { None => Ok(()), @@ -717,7 +717,6 @@ impl Explorer { if line == "y" { let item = explorer.tree.current_item(); std::fs::remove_dir_all(&item.path)?; - explorer.tree.fold_current_child(); explorer.tree.remove_current(); } } diff --git a/helix-term/src/ui/tree.rs b/helix-term/src/ui/tree.rs index 35929a82..117ff1f1 100644 --- a/helix-term/src/ui/tree.rs +++ b/helix-term/src/ui/tree.rs @@ -129,60 +129,25 @@ impl<'a, T> DoubleEndedIterator for TreeIter<'a, T> { impl<'a, T> ExactSizeIterator for TreeIter<'a, T> {} -impl Tree { - pub fn filter

(tree: &Tree, predicate: &P) -> Option> - where - P: Fn(&T) -> bool, - { - let children = tree - .children - .iter() - .filter_map(|tree| Self::filter(tree, predicate)) - .collect::>(); - if tree.item.is_parent() || predicate(&tree.item) { - let mut tree = Tree { - item: tree.item.clone(), - parent_index: tree.parent_index, - index: tree.index, - is_opened: tree.is_opened, - children, - }; - tree.regenerate_index(); - Some(tree) - } else { - None - } - } -} - impl Tree { fn open(&mut self, filter: &String) -> Result<()> { if self.item.is_parent() { - self.children = vec_to_tree( - self.item - .get_children()? - .into_iter() - .filter(|item| item.name().to_lowercase().contains(&filter.to_lowercase())) - .collect(), - ); + self.children = self.get_filtered_children(filter)?; self.is_opened = true; } Ok(()) } + fn close(&mut self) { + self.is_opened = false; + self.children = vec![]; + } + fn refresh(&mut self, filter: &String) -> Result<()> { if !self.is_opened { return Ok(()); } - let latest_children = vec_to_tree( - self.item - .get_children()? - .into_iter() - .filter(|item| { - item.is_parent() || item.name().to_lowercase().contains(&filter.to_lowercase()) - }) - .collect(), - ); + let latest_children = self.get_filtered_children(filter)?; let filtered = std::mem::replace(&mut self.children, vec![]) .into_iter() // Remove children that does not exists in latest_children @@ -216,6 +181,18 @@ impl Tree { Ok(()) } + fn get_filtered_children(&self, filter: &String) -> Result>> { + Ok(vec_to_tree( + self.item + .get_children()? + .into_iter() + .filter(|item| { + item.is_parent() || item.name().to_lowercase().contains(&filter.to_lowercase()) + }) + .collect(), + )) + } + fn sort(&mut self) { self.children .sort_by(|a, b| tree_item_cmp(&a.item, &b.item)) @@ -514,23 +491,9 @@ impl TreeView { selected_index: usize, filter: &String, ) { - // if let Some(next_level) = self.next_item().map(|elem| elem.level) { - // let current = self.find_by_index(selected_index); - // let current_level = current.level; - // if next_level > current_level { - // // if let Some(mut on_folded_fn) = self.on_folded_fn.take() { - // // on_folded_fn(&mut current.item, cx, params); - // // self.on_folded_fn = Some(on_folded_fn); - // // } - // self.fold_current_child(); - // return; - // } - // } - // - let mut selected_item = self.get_mut(selected_index); + let selected_item = self.get_mut(selected_index); if selected_item.is_opened { - selected_item.is_opened = false; - selected_item.children = vec![]; + selected_item.close(); self.regenerate_index(); return; } @@ -553,15 +516,6 @@ impl TreeView { } } - pub fn fold_current_child(&mut self) { - if let Some(parent) = self.current_parent_mut() { - parent.is_opened = false; - parent.children = vec![]; - self.selected = parent.index; - self.regenerate_index() - } - } - pub fn search_next(&mut self, s: &str) { let skip = std::cmp::max(2, self.save_view.0 + 1); self.set_selected( @@ -684,14 +638,6 @@ impl TreeView { } } - fn current_parent_mut(&mut self) -> Option<&mut Tree> { - if let Some(parent_index) = self.current().parent_index { - Some(self.get_mut(parent_index)) - } else { - None - } - } - pub fn current_item(&self) -> &T { &self.current().item } @@ -718,10 +664,10 @@ impl TreeView { let item_name = item.name(); if !tree.is_opened { tree.open(filter)?; + } else { + tree.refresh(filter)?; } - tree.children.push(Tree::new(item, vec![])); - tree.children - .sort_by(|a, b| tree_item_cmp(&a.item, &b.item)); + self.regenerate_index(); let tree = self.get(index); @@ -893,7 +839,6 @@ impl TreeView { key!('j') | key!(Tab) | key!(Down) | ctrl!('j') => self.move_down(1.max(count)), key!('z') => { self.on_next_key = Some(Box::new(|_, tree, event| match event.into() { - key!('f') => tree.fold_current_child(), key!('z') => tree.align_view_center(), key!('t') => tree.align_view_top(), key!('b') => tree.align_view_bottom(), @@ -965,8 +910,6 @@ fn index_elems(parent_index: usize, elems: Vec>) -> Vec> { mod test_tree { use helix_core::movement::Direction; - use crate::ui::TreeItem; - use super::Tree; #[test] @@ -1118,95 +1061,6 @@ mod test_tree { assert_eq!(result, Some(3)); } - #[test] - fn test_filter() { - #[derive(Clone, Debug, PartialEq, Eq)] - struct MyItem<'a>(bool, &'a str); - impl<'a> TreeItem for MyItem<'a> { - type Params = (); - fn name(&self) -> String { - self.0.to_string() - } - fn is_child(&self, _: &Self) -> bool { - !self.0 - } - fn is_parent(&self) -> bool { - self.0 - } - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.1.cmp(other.1) - } - } - let tree = Tree::new( - MyItem(false, ".cargo"), - vec![ - Tree::new( - MyItem(true, "spam"), - vec![Tree::new(MyItem(false, "Cargo.toml"), vec![])], - ), - Tree::new( - MyItem(true, "Cargo.toml"), - vec![Tree::new(MyItem(false, "pam"), vec![])], - ), - Tree::new(MyItem(false, "hello"), vec![]), - ], - ); - - let result = Tree::filter(&tree, &|item| item.1.to_lowercase().contains("cargo")); - assert_eq!( - result, - Some(Tree::new( - MyItem(false, ".cargo"), - vec![ - Tree::new( - MyItem(true, "spam"), - vec![Tree::new(MyItem(false, "Cargo.toml"), vec![])] - ), - Tree { - is_opened: true, - ..Tree::new(MyItem(true, "Cargo.toml"), vec![]) - }, - ], - )) - ); - - let result = Tree::filter(&tree, &|item| item.1.to_lowercase().contains("pam")); - assert_eq!( - result, - Some(Tree::new( - MyItem(false, ".cargo"), - vec![ - Tree { - is_opened: true, - ..Tree::new(MyItem(true, "spam"), vec![]) - }, - Tree::new( - MyItem(true, "Cargo.toml"), - vec![Tree::new(MyItem(false, "pam"), vec![])] - ), - ], - )) - ); - - let result = Tree::filter(&tree, &|item| item.1.to_lowercase().contains("helix")); - assert_eq!( - result, - Some(Tree::new( - MyItem(false, ".cargo"), - vec![ - Tree { - is_opened: true, - ..Tree::new(MyItem(true, "spam"), vec![]) - }, - Tree { - is_opened: true, - ..Tree::new(MyItem(true, "Cargo.toml"), vec![]) - } - ], - )) - ) - } - #[test] fn test_remove() { let mut tree = Tree::new(