From bdab93e856148f2624175fdb0c697fd23e197ec9 Mon Sep 17 00:00:00 2001 From: wongjiahau Date: Sun, 12 Feb 2023 19:59:17 +0800 Subject: [PATCH] feat(explore): search --- helix-term/src/ui/explore.rs | 61 ++++++++++++++++-------------------- helix-term/src/ui/tree.rs | 48 +++++++++++++++++----------- 2 files changed, 56 insertions(+), 53 deletions(-) diff --git a/helix-term/src/ui/explore.rs b/helix-term/src/ui/explore.rs index 2e852e6e..462a0aa8 100644 --- a/helix-term/src/ui/explore.rs +++ b/helix-term/src/ui/explore.rs @@ -78,30 +78,30 @@ impl FileInfo { impl TreeItem for FileInfo { type Params = State; - fn text(&self, cx: &mut Context, selected: bool, state: &mut State) -> Spans { - let text = self.get_text(); - let theme = &cx.editor.theme; - - let style = match self.file_type { - FileType::Parent | FileType::Dir | FileType::Root => "ui.explorer.dir", - FileType::File | FileType::Exe | FileType::Placeholder => "ui.explorer.file", - }; - let style = theme.try_get(style).unwrap_or_else(|| theme.get("ui.text")); - let style = if !selected { - style - } else { - let patch = match state.focus { - true => "ui.explorer.focus", - false => "ui.explorer.unfocus", - }; - if let Some(patch) = theme.try_get(patch) { - style.patch(patch) - } else { - style.add_modifier(Modifier::REVERSED) - } - }; - Spans::from(Span::styled(text, style)) - } + // fn text(&self, cx: &mut Context, selected: bool, state: &mut State) -> Spans { + // let text = self.get_text(); + // let theme = &cx.editor.theme; + + // let style = match self.file_type { + // FileType::Parent | FileType::Dir | FileType::Root => "ui.explorer.dir", + // FileType::File | FileType::Exe | FileType::Placeholder => "ui.explorer.file", + // }; + // let style = theme.try_get(style).unwrap_or_else(|| theme.get("ui.text")); + // let style = if !selected { + // style + // } else { + // let patch = match state.focus { + // true => "ui.explorer.focus", + // false => "ui.explorer.unfocus", + // }; + // if let Some(patch) = theme.try_get(patch) { + // style.patch(patch) + // } else { + // style.add_modifier(Modifier::REVERSED) + // } + // }; + // Spans::from(Span::styled(text, style)) + // } fn is_child(&self, other: &Self) -> bool { if let FileType::Parent = other.file_type { @@ -175,14 +175,6 @@ impl TreeItem for FileInfo { Ok(ret) } - fn filter(&self, s: &str) -> bool { - if s.is_empty() { - false - } else { - self.get_text().contains(s) - } - } - fn text_string(&self) -> String { self.get_text().to_string() } @@ -667,7 +659,7 @@ impl Explorer { } else { explorer .tree - .search_pre(cx, &search_str, &mut explorer.state); + .search_previous(cx, &search_str, &mut explorer.state); } } })) @@ -684,7 +676,8 @@ impl Explorer { if search_next { self.tree.search_next(cx, prompt.line(), &mut self.state); } else { - self.tree.search_pre(cx, prompt.line(), &mut self.state); + self.tree + .search_previous(cx, prompt.line(), &mut self.state); } } self.prompt = Some((action, prompt)); diff --git a/helix-term/src/ui/tree.rs b/helix-term/src/ui/tree.rs index 4fad6dcd..c9a97b84 100644 --- a/helix-term/src/ui/tree.rs +++ b/helix-term/src/ui/tree.rs @@ -17,14 +17,16 @@ use tui::{buffer::Buffer as Surface, text::Spans}; pub trait TreeItem: Sized { type Params; - fn text(&self, cx: &mut Context, selected: bool, params: &mut Self::Params) -> Spans; + // fn text(&self, cx: &mut Context, selected: bool, params: &mut Self::Params) -> Spans; fn text_string(&self) -> String; fn is_child(&self, other: &Self) -> bool; fn is_parent(&self) -> bool; fn cmp(&self, other: &Self) -> Ordering; fn filter(&self, s: &str) -> bool { - self.text_string().contains(s) + self.text_string() + .to_lowercase() + .contains(&s.to_lowercase()) } fn get_children(&self) -> Result> { @@ -124,8 +126,10 @@ impl Clone for Tree { } } +#[derive(Clone)] struct TreeIter<'a, T> { - current_index: usize, + current_index_forward: usize, + current_index_reverse: isize, tree: &'a Tree, } @@ -133,32 +137,40 @@ impl<'a, T> Iterator for TreeIter<'a, T> { type Item = &'a Tree; fn next(&mut self) -> Option { - let index = self.current_index; - self.current_index += 1; + let index = self.current_index_forward; + if index > self.tree.len().saturating_sub(1) { + None + } else { + self.current_index_forward = self.current_index_forward.saturating_add(1); + self.tree.find_by_index(index) + } + } - self.tree.find_by_index(index) + fn size_hint(&self) -> (usize, Option) { + (self.tree.len(), Some(self.tree.len())) } } impl<'a, T> DoubleEndedIterator for TreeIter<'a, T> { fn next_back(&mut self) -> Option { - let index = self.current_index; - self.current_index -= 1; - self.tree.find_by_index(index) + let index = self.current_index_reverse; + if index < 0 { + None + } else { + self.current_index_reverse = self.current_index_reverse.saturating_sub(1); + self.tree.find_by_index(index as usize) + } } } -impl<'a, T> ExactSizeIterator for TreeIter<'a, T> { - fn len(&self) -> usize { - self.tree.len() - } -} +impl<'a, T> ExactSizeIterator for TreeIter<'a, T> {} impl Tree { fn iter(&self) -> TreeIter { TreeIter { tree: self, - current_index: 0, + current_index_forward: 0, + current_index_reverse: (self.len() - 1) as isize, } } pub fn new(item: T, children: Vec>) -> Self { @@ -294,7 +306,7 @@ impl TreeView { if reverse { iter.take(start).rposition(f) } else { - iter.skip(start).position(f).map(|p| p + start) + iter.skip(start).position(f).map(|index| index + start) } } @@ -490,7 +502,7 @@ impl TreeView { self.winline = (self.save_view.1 + self.selected).saturating_sub(self.save_view.0); } - pub fn search_pre(&mut self, cx: &mut Context, s: &str, params: &mut T::Params) { + pub fn search_previous(&mut self, cx: &mut Context, s: &str, params: &mut T::Params) { let take = self.save_view.0; self.selected = self .find(take, true, |e| e.item.filter(s)) @@ -645,8 +657,6 @@ impl TreeView { let last_item_index = self.tree.len().saturating_sub(1); let skip = self.selected.saturating_sub(self.winline); - cx.editor.set_error(format!("winline = {}", self.winline)); - let params = RenderElemParams { tree: &self.tree, prefix: &"".to_string(),