feat(explore): search

pull/9/head
wongjiahau 2 years ago
parent aa397ef801
commit bdab93e856

@ -78,30 +78,30 @@ impl FileInfo {
impl TreeItem for FileInfo { impl TreeItem for FileInfo {
type Params = State; type Params = State;
fn text(&self, cx: &mut Context, selected: bool, state: &mut State) -> Spans { // fn text(&self, cx: &mut Context, selected: bool, state: &mut State) -> Spans {
let text = self.get_text(); // let text = self.get_text();
let theme = &cx.editor.theme; // let theme = &cx.editor.theme;
let style = match self.file_type { // let style = match self.file_type {
FileType::Parent | FileType::Dir | FileType::Root => "ui.explorer.dir", // FileType::Parent | FileType::Dir | FileType::Root => "ui.explorer.dir",
FileType::File | FileType::Exe | FileType::Placeholder => "ui.explorer.file", // FileType::File | FileType::Exe | FileType::Placeholder => "ui.explorer.file",
}; // };
let style = theme.try_get(style).unwrap_or_else(|| theme.get("ui.text")); // let style = theme.try_get(style).unwrap_or_else(|| theme.get("ui.text"));
let style = if !selected { // let style = if !selected {
style // style
} else { // } else {
let patch = match state.focus { // let patch = match state.focus {
true => "ui.explorer.focus", // true => "ui.explorer.focus",
false => "ui.explorer.unfocus", // false => "ui.explorer.unfocus",
}; // };
if let Some(patch) = theme.try_get(patch) { // if let Some(patch) = theme.try_get(patch) {
style.patch(patch) // style.patch(patch)
} else { // } else {
style.add_modifier(Modifier::REVERSED) // style.add_modifier(Modifier::REVERSED)
} // }
}; // };
Spans::from(Span::styled(text, style)) // Spans::from(Span::styled(text, style))
} // }
fn is_child(&self, other: &Self) -> bool { fn is_child(&self, other: &Self) -> bool {
if let FileType::Parent = other.file_type { if let FileType::Parent = other.file_type {
@ -175,14 +175,6 @@ impl TreeItem for FileInfo {
Ok(ret) Ok(ret)
} }
fn filter(&self, s: &str) -> bool {
if s.is_empty() {
false
} else {
self.get_text().contains(s)
}
}
fn text_string(&self) -> String { fn text_string(&self) -> String {
self.get_text().to_string() self.get_text().to_string()
} }
@ -667,7 +659,7 @@ impl Explorer {
} else { } else {
explorer explorer
.tree .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 { if search_next {
self.tree.search_next(cx, prompt.line(), &mut self.state); self.tree.search_next(cx, prompt.line(), &mut self.state);
} else { } 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)); self.prompt = Some((action, prompt));

@ -17,14 +17,16 @@ use tui::{buffer::Buffer as Surface, text::Spans};
pub trait TreeItem: Sized { pub trait TreeItem: Sized {
type Params; 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 text_string(&self) -> String;
fn is_child(&self, other: &Self) -> bool; fn is_child(&self, other: &Self) -> bool;
fn is_parent(&self) -> bool; fn is_parent(&self) -> bool;
fn cmp(&self, other: &Self) -> Ordering; fn cmp(&self, other: &Self) -> Ordering;
fn filter(&self, s: &str) -> bool { 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<Vec<Self>> { fn get_children(&self) -> Result<Vec<Self>> {
@ -124,8 +126,10 @@ impl<T: Clone> Clone for Tree<T> {
} }
} }
#[derive(Clone)]
struct TreeIter<'a, T> { struct TreeIter<'a, T> {
current_index: usize, current_index_forward: usize,
current_index_reverse: isize,
tree: &'a Tree<T>, tree: &'a Tree<T>,
} }
@ -133,32 +137,40 @@ impl<'a, T> Iterator for TreeIter<'a, T> {
type Item = &'a Tree<T>; type Item = &'a Tree<T>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let index = self.current_index; let index = self.current_index_forward;
self.current_index += 1; 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<usize>) {
(self.tree.len(), Some(self.tree.len()))
} }
} }
impl<'a, T> DoubleEndedIterator for TreeIter<'a, T> { impl<'a, T> DoubleEndedIterator for TreeIter<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> { fn next_back(&mut self) -> Option<Self::Item> {
let index = self.current_index; let index = self.current_index_reverse;
self.current_index -= 1; if index < 0 {
self.tree.find_by_index(index) 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> { impl<'a, T> ExactSizeIterator for TreeIter<'a, T> {}
fn len(&self) -> usize {
self.tree.len()
}
}
impl<T> Tree<T> { impl<T> Tree<T> {
fn iter(&self) -> TreeIter<T> { fn iter(&self) -> TreeIter<T> {
TreeIter { TreeIter {
tree: self, tree: self,
current_index: 0, current_index_forward: 0,
current_index_reverse: (self.len() - 1) as isize,
} }
} }
pub fn new(item: T, children: Vec<Tree<T>>) -> Self { pub fn new(item: T, children: Vec<Tree<T>>) -> Self {
@ -294,7 +306,7 @@ impl<T: TreeItem> TreeView<T> {
if reverse { if reverse {
iter.take(start).rposition(f) iter.take(start).rposition(f)
} else { } else {
iter.skip(start).position(f).map(|p| p + start) iter.skip(start).position(f).map(|index| index + start)
} }
} }
@ -490,7 +502,7 @@ impl<T: TreeItem> TreeView<T> {
self.winline = (self.save_view.1 + self.selected).saturating_sub(self.save_view.0); 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; let take = self.save_view.0;
self.selected = self self.selected = self
.find(take, true, |e| e.item.filter(s)) .find(take, true, |e| e.item.filter(s))
@ -645,8 +657,6 @@ impl<T: TreeItem> TreeView<T> {
let last_item_index = self.tree.len().saturating_sub(1); let last_item_index = self.tree.len().saturating_sub(1);
let skip = self.selected.saturating_sub(self.winline); let skip = self.selected.saturating_sub(self.winline);
cx.editor.set_error(format!("winline = {}", self.winline));
let params = RenderElemParams { let params = RenderElemParams {
tree: &self.tree, tree: &self.tree,
prefix: &"".to_string(), prefix: &"".to_string(),

Loading…
Cancel
Save