diff --git a/helix-term/src/ui/explore.rs b/helix-term/src/ui/explore.rs index c1ec0067..d2bb1b5b 100644 --- a/helix-term/src/ui/explore.rs +++ b/helix-term/src/ui/explore.rs @@ -240,7 +240,7 @@ impl Explorer { pub fn reveal_current_file(&mut self, cx: &mut Context) -> Result<()> { let current_document_path = doc!(cx.editor).path().cloned(); match current_document_path { - None => Err(anyhow::anyhow!("No opened document.")), + None => Ok(()), Some(current_path) => self.reveal_file(current_path), } } @@ -499,15 +499,26 @@ impl Explorer { self.render_preview(preview_area, surface, cx.editor); let list_area = render_block(area.clip_right(preview_area.width), surface, Borders::RIGHT); + self.render_tree(list_area, surface, cx) + } + + fn render_tree(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) { surface.set_stringn( - list_area.x, - list_area.y, + area.x, + area.y, " Explorer: press ? for help", - list_area.width.into(), + area.width.into(), + cx.editor.theme.get("ui.text"), + ); + surface.set_stringn( + area.x, + area.y.saturating_add(1), + format!(" [FILTER]: {}", self.state.filter), + area.width.into(), cx.editor.theme.get("ui.text"), ); self.tree - .render(list_area.clip_top(1), surface, cx, &self.state.filter); + .render(area.clip_top(2), surface, cx, &self.state.filter); } pub fn render_embed( @@ -546,15 +557,7 @@ impl Explorer { render_block(side_area.clip_right(1), surface, Borders::LEFT).clip_bottom(1) } }; - surface.set_stringn( - list_area.x.saturating_sub(1), - list_area.y, - " Explorer: press ? for help", - list_area.width.into(), - cx.editor.theme.get("ui.text"), - ); - self.tree - .render(list_area.clip_top(1), surface, cx, &self.state.filter); + self.render_tree(list_area, surface, cx); { let statusline = if self.is_focus() { @@ -568,15 +571,6 @@ impl Explorer { ExplorerPositionEmbed::Right => area.clip_left(1), }; surface.clear_with(area, statusline); - // surface.set_string_truncated( - // area.x, - // area.y, - // &self.path_state.root.to_string_lossy(), - // area.width as usize, - // |_| statusline, - // true, - // true, - // ); } if self.is_focus() { @@ -616,28 +610,27 @@ impl Explorer { fn handle_filter_event(&mut self, event: KeyEvent, cx: &mut Context) -> EventResult { let (action, mut prompt) = self.prompt.take().unwrap(); - match event.into() { - key!(Tab) | key!(Down) | ctrl!('j') => { - self.tree.clean_recycle(); - let filter = self.state.filter.clone(); - return self - .tree - .handle_event(Event::Key(event), cx, &mut self.state, &filter); - } - key!(Enter) => { - if let EventResult::Consumed(_) = prompt.handle_event(Event::Key(event), cx) { - self.tree.filter(prompt.line()); + (|| -> Result<()> { + match event.into() { + key!(Enter) => { + if let EventResult::Consumed(_) = prompt.handle_event(Event::Key(event), cx) { + self.tree.refresh(prompt.line())?; + } } - } - key!(Esc) | ctrl!('c') => self.tree.restore_recycle(), - _ => { - if let EventResult::Consumed(_) = prompt.handle_event(Event::Key(event), cx) { - self.tree.filter(prompt.line()); + key!(Esc) | ctrl!('c') => { + self.state.filter.clear(); } - self.state.filter = prompt.line().clone(); - self.prompt = Some((action, prompt)); - } - }; + _ => { + if let EventResult::Consumed(_) = prompt.handle_event(Event::Key(event), cx) { + self.tree.refresh(prompt.line())?; + } + self.state.filter = prompt.line().clone(); + self.prompt = Some((action, prompt)); + } + }; + Ok(()) + })() + .unwrap_or_else(|err| cx.editor.set_error(format!("{err}"))); EventResult::Consumed(None) } @@ -673,9 +666,6 @@ impl Explorer { } else { self.repeat_motion = None; } - // return self - // .tree - // .handle_event(Event::Key(event), cx, &mut self.state); } key!(Esc) | ctrl!('c') => self.tree.restore_view(), _ => { diff --git a/helix-term/src/ui/tree.rs b/helix-term/src/ui/tree.rs index 229b92bd..f7f48091 100644 --- a/helix-term/src/ui/tree.rs +++ b/helix-term/src/ui/tree.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, cmp::Ordering}; +use std::cmp::Ordering; use anyhow::Result; use helix_view::theme::Modifier; @@ -139,7 +139,7 @@ impl Tree { .iter() .filter_map(|tree| Self::filter(tree, predicate)) .collect::>(); - if tree.item.is_parent() || predicate(&tree.item) || !children.is_empty() { + if tree.item.is_parent() || predicate(&tree.item) { let mut tree = Tree { item: tree.item.clone(), parent_index: tree.parent_index, @@ -178,7 +178,9 @@ impl Tree { self.item .get_children()? .into_iter() - .filter(|item| item.name().to_lowercase().contains(&filter.to_lowercase())) + .filter(|item| { + item.is_parent() || item.name().to_lowercase().contains(&filter.to_lowercase()) + }) .collect(), ); let filtered = std::mem::replace(&mut self.children, vec![]) @@ -267,15 +269,6 @@ impl Tree { } else { self.children.iter().find_map(|elem| elem.get(index)) } - // self.traverse(None, &|result, current_index, tree| { - // result.or_else(|| { - // if index == current_index { - // Some(tree) - // } else { - // None - // } - // }) - // }) } fn traverse<'a, U, F>(&'a self, init: U, f: &F) -> U where @@ -353,7 +346,6 @@ impl Tree { pub struct TreeView { tree: Tree, - recycle: Option<(String, Tree)>, /// Selected item idex selected: usize, @@ -382,7 +374,6 @@ impl TreeView { pub fn new(root: T, items: Vec>) -> Self { Self { tree: Tree::new(root, items), - recycle: None, selected: 0, save_view: (0, 0), winline: 0, @@ -938,45 +929,6 @@ impl TreeView { } } -impl TreeView { - pub fn filter(&mut self, s: &str) { - if s.is_empty() { - self.restore_recycle(); - return; - } - - let new_tree = Tree::filter(&self.tree, &|item: &T| { - item.name().to_lowercase().contains(&s.to_lowercase()) - }) - .unwrap_or_else(|| Tree { - item: self.tree.item.clone(), - children: vec![], - ..self.tree.clone() - }); - let recycle = std::mem::replace(&mut self.tree, new_tree); - if let Some(r) = self.recycle.as_mut() { - r.0 = s.into() - } else { - self.recycle = Some((s.into(), recycle)); - self.save_view(); - } - - self.selected = 0; - self.winline = 0 - } - - pub fn clean_recycle(&mut self) { - self.recycle = None; - } - - pub fn restore_recycle(&mut self) { - if let Some((_, recycle)) = self.recycle.take() { - self.tree = recycle; - } - self.restore_view(); - } -} - /// Recalculate the index of each item of a tree. /// /// For example: