fix(explore): filter

pull/9/head
wongjiahau 2 years ago
parent 85fa1c56b7
commit 9bd534bb6f

@ -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(),
_ => {

@ -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<T: Clone + TreeItem> Tree<T> {
.iter()
.filter_map(|tree| Self::filter(tree, predicate))
.collect::<Vec<_>>();
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<T: TreeItem> Tree<T> {
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<T> Tree<T> {
} 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<T> Tree<T> {
pub struct TreeView<T: TreeItem> {
tree: Tree<T>,
recycle: Option<(String, Tree<T>)>,
/// Selected item idex
selected: usize,
@ -382,7 +374,6 @@ impl<T: TreeItem> TreeView<T> {
pub fn new(root: T, items: Vec<Tree<T>>) -> Self {
Self {
tree: Tree::new(root, items),
recycle: None,
selected: 0,
save_view: (0, 0),
winline: 0,
@ -938,45 +929,6 @@ impl<T: TreeItem + Clone> TreeView<T> {
}
}
impl<T: TreeItem + Clone> TreeView<T> {
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:

Loading…
Cancel
Save