fix(compile): warnings

pull/9/head
wongjiahau 1 year ago
parent 56056e8556
commit a079477a23

@ -433,7 +433,7 @@ impl MappableCommand {
record_macro, "Record macro",
replay_macro, "Replay macro",
command_palette, "Open command pallete",
toggle_or_focus_explorer, "Toggle or focus explorer",
open_or_focus_explorer, "Open or focus explorer",
reveal_current_file, "Reveal current file in explorer",
close_explorer, "close explorer",
);
@ -2216,7 +2216,7 @@ fn file_picker_in_current_directory(cx: &mut Context) {
cx.push_layer(Box::new(overlayed(picker)));
}
fn toggle_or_focus_explorer(cx: &mut Context) {
fn open_or_focus_explorer(cx: &mut Context) {
cx.callback = Some(Box::new(
|compositor: &mut Compositor, cx: &mut compositor::Context| {
if let Some(editor) = compositor.find::<ui::EditorView>() {
@ -2236,17 +2236,19 @@ fn reveal_current_file(cx: &mut Context) {
cx.callback = Some(Box::new(
|compositor: &mut Compositor, cx: &mut compositor::Context| {
if let Some(editor) = compositor.find::<ui::EditorView>() {
match editor.explorer.as_mut() {
(|| match editor.explorer.as_mut() {
Some(explore) => explore.content.reveal_current_file(cx),
None => match ui::Explorer::new(cx) {
Ok(explore) => {
let mut explorer = overlayed(explore);
explorer.content.reveal_current_file(cx);
editor.explorer = Some(explorer);
}
Err(err) => cx.editor.set_error(format!("{}", err)),
},
}
None => {
editor.explorer = Some(overlayed(ui::Explorer::new(cx)?));
let explorer = editor.explorer.as_mut().unwrap();
explorer.content.reveal_current_file(cx)?;
explorer.content.focus();
Ok(())
}
})()
.unwrap_or_else(|err| {
cx.editor.set_error(err.to_string())
})
}
},
));

@ -264,8 +264,8 @@ pub fn default() -> HashMap<Mode, Keymap> {
"r" => rename_symbol,
"h" => select_references_to_symbol_under_cursor,
"?" => command_palette,
"e" => toggle_or_focus_explorer,
"E" => reveal_current_file,
"e" => reveal_current_file,
"E" => open_or_focus_explorer,
},
"z" => { "View"
"z" | "c" => align_view_center,

@ -1,6 +1,6 @@
use super::{Prompt, TreeItem, TreeOp, TreeView};
use crate::{
compositor::{Component, Compositor, Context, EventResult},
compositor::{Component, Context, EventResult},
ctrl, key, shift, ui,
};
use anyhow::{bail, ensure, Result};
@ -148,6 +148,7 @@ struct State {
open: bool,
current_root: PathBuf,
area_width: u16,
filter: String,
}
impl State {
@ -157,6 +158,7 @@ impl State {
current_root,
open: true,
area_width: 0,
filter: "".to_string(),
}
}
}
@ -215,7 +217,7 @@ impl Explorer {
}
}
fn reveal_file(&mut self, cx: &mut Context, path: PathBuf) {
fn reveal_file(&mut self, path: PathBuf) -> Result<()> {
let current_root = &self.state.current_root;
let current_path = path.as_path().to_string_lossy().to_string();
let current_root = current_root.as_path().to_string_lossy().to_string() + "/";
@ -230,19 +232,16 @@ impl Explorer {
)
.split(std::path::MAIN_SEPARATOR)
.collect::<Vec<_>>();
match self.tree.reveal_item(segments) {
Ok(_) => {
self.focus();
}
Err(error) => cx.editor.set_error(error.to_string()),
}
self.tree.reveal_item(segments)?;
self.focus();
Ok(())
}
pub fn reveal_current_file(&mut self, cx: &mut Context) {
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 => cx.editor.set_error("No opened document."),
Some(current_path) => self.reveal_file(cx, current_path),
None => Err(anyhow::anyhow!("No opened document.")),
Some(current_path) => self.reveal_file(current_path),
}
}
@ -457,11 +456,7 @@ impl Explorer {
));
}
fn toggle_current(
item: &mut FileInfo,
cx: &mut Context,
state: &mut State,
) -> TreeOp<FileInfo> {
fn toggle_current(item: &mut FileInfo, cx: &mut Context, state: &mut State) -> TreeOp {
if item.path == Path::new("") {
return TreeOp::Noop;
}
@ -629,13 +624,13 @@ impl Explorer {
}
key!(Enter) => {
if let EventResult::Consumed(_) = prompt.handle_event(Event::Key(event), cx) {
self.tree.filter(prompt.line(), cx, &mut self.state);
self.tree.filter(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(), cx, &mut self.state);
self.tree.filter(prompt.line());
}
self.prompt = Some((action, prompt));
}
@ -658,20 +653,16 @@ impl Explorer {
key!(Enter) => {
let search_str = prompt.line().clone();
if !search_str.is_empty() {
self.repeat_motion = Some(Box::new(move |explorer, action, cx| {
self.repeat_motion = Some(Box::new(move |explorer, action, _| {
if let PromptAction::Search {
search_next: is_next,
} = action
{
explorer.tree.save_view();
if is_next == search_next {
explorer
.tree
.search_next(cx, &search_str, &mut explorer.state);
explorer.tree.search_next(&search_str);
} else {
explorer
.tree
.search_previous(cx, &search_str, &mut explorer.state);
explorer.tree.search_previous(&search_str);
}
}
}))
@ -686,10 +677,9 @@ impl Explorer {
_ => {
if let EventResult::Consumed(_) = prompt.handle_event(Event::Key(event), cx) {
if search_next {
self.tree.search_next(cx, prompt.line(), &mut self.state);
self.tree.search_next(prompt.line());
} else {
self.tree
.search_previous(cx, prompt.line(), &mut self.state);
self.tree.search_previous(prompt.line());
}
}
self.prompt = Some((action, prompt));
@ -704,71 +694,67 @@ impl Explorer {
Some((PromptAction::Filter, _)) => return self.handle_filter_event(event, cx),
_ => {}
};
let (action, mut prompt) = match self.prompt.take() {
Some((action, p)) => (action, p),
_ => return EventResult::Ignored(None),
};
let line = prompt.line();
match (&action, event.into()) {
(
PromptAction::CreateFolder {
folder_path,
parent_index,
},
key!(Enter),
) => {
if let Err(e) = self.new_path(folder_path.clone(), line, true, *parent_index) {
cx.editor.set_error(format!("{e}"))
}
}
(
PromptAction::CreateFile {
folder_path,
parent_index,
},
key!(Enter),
) => {
if let Err(e) = self.new_path(folder_path.clone(), line, false, *parent_index) {
cx.editor.set_error(format!("{e}"))
}
}
(PromptAction::RemoveDir, key!(Enter)) => {
if line == "y" {
let item = self.tree.current_item();
if let Err(e) = std::fs::remove_dir_all(&item.path) {
cx.editor.set_error(format!("{e}"));
} else {
self.tree.fold_current_child();
self.tree.remove_current();
fn handle_prompt_event(
explorer: &mut Explorer,
event: KeyEvent,
cx: &mut Context,
) -> Result<EventResult> {
let (action, mut prompt) = match explorer.prompt.take() {
Some((action, p)) => (action, p),
_ => return Ok(EventResult::Ignored(None)),
};
let line = prompt.line();
match (&action, event.into()) {
(
PromptAction::CreateFolder {
folder_path,
parent_index,
},
key!(Enter),
) => explorer.new_path(folder_path.clone(), line, true, *parent_index)?,
(
PromptAction::CreateFile {
folder_path,
parent_index,
},
key!(Enter),
) => explorer.new_path(folder_path.clone(), line, false, *parent_index)?,
(PromptAction::RemoveDir, key!(Enter)) => {
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();
}
}
}
(PromptAction::RemoveFile, key!(Enter)) => {
if line == "y" {
let item = self.tree.current_item();
if let Err(e) = std::fs::remove_file(&item.path) {
cx.editor.set_error(format!("{e}"));
} else {
self.tree.remove_current();
(PromptAction::RemoveFile, key!(Enter)) => {
if line == "y" {
let item = explorer.tree.current_item();
std::fs::remove_file(&item.path).map_err(anyhow::Error::from)?;
explorer.tree.remove_current();
}
}
}
(PromptAction::RenameFile, key!(Enter)) => {
let item = self.tree.current_item();
if let Err(e) = std::fs::rename(&item.path, line) {
cx.editor.set_error(format!("{e}"));
} else {
self.tree.remove_current();
self.reveal_file(cx, PathBuf::from(line))
(PromptAction::RenameFile, key!(Enter)) => {
let item = explorer.tree.current_item();
std::fs::rename(&item.path, line)?;
explorer.tree.remove_current();
explorer.reveal_file(PathBuf::from(line))?;
}
(_, key!(Esc) | ctrl!('c')) => {}
_ => {
prompt.handle_event(Event::Key(event), cx);
explorer.prompt = Some((action, prompt));
}
}
(_, key!(Esc) | ctrl!('c')) => {}
_ => {
prompt.handle_event(Event::Key(event), cx);
self.prompt = Some((action, prompt));
Ok(EventResult::Consumed(None))
}
match handle_prompt_event(self, event, cx) {
Ok(event_result) => event_result,
Err(err) => {
cx.editor.set_error(err.to_string());
EventResult::Consumed(None)
}
}
EventResult::Consumed(None)
}
fn new_path(

@ -1,4 +1,4 @@
use std::{cmp::Ordering, path::PathBuf};
use std::cmp::Ordering;
use anyhow::Result;
use helix_view::theme::Modifier;
@ -7,12 +7,12 @@ use crate::{
compositor::{Context, EventResult},
ctrl, key, shift,
};
use helix_core::{movement::Direction, unicode::width::UnicodeWidthStr};
use helix_core::movement::Direction;
use helix_view::{
graphics::Rect,
input::{Event, KeyEvent},
};
use tui::{buffer::Buffer as Surface, text::Spans};
use tui::buffer::Buffer as Surface;
pub trait TreeItem: Sized {
type Params;
@ -54,12 +54,9 @@ fn vec_to_tree<T: TreeItem>(mut items: Vec<T>) -> Vec<Tree<T>> {
)
}
pub enum TreeOp<T> {
pub enum TreeOp {
Noop,
Restore,
InsertChild(Vec<T>),
GetChildsAndInsert,
ReplaceTree { root: T, children: Vec<T> },
}
#[derive(Debug, PartialEq, Eq)]
@ -132,7 +129,7 @@ impl<'a, T> DoubleEndedIterator for TreeIter<'a, T> {
impl<'a, T> ExactSizeIterator for TreeIter<'a, T> {}
impl<T: Clone> Tree<T> {
impl<T: Clone + TreeItem> Tree<T> {
pub fn filter<P>(tree: &Tree<T>, predicate: &P) -> Option<Tree<T>>
where
P: Fn(&T) -> bool,
@ -142,7 +139,7 @@ impl<T: Clone> Tree<T> {
.iter()
.filter_map(|tree| Self::filter(tree, predicate))
.collect::<Vec<_>>();
if predicate(&tree.item) || !children.is_empty() {
if tree.item.is_parent() || predicate(&tree.item) || !children.is_empty() {
let mut tree = Tree {
item: tree.item.clone(),
parent_index: tree.parent_index,
@ -156,14 +153,6 @@ impl<T: Clone> Tree<T> {
None
}
}
pub fn parent_index(&self) -> Option<usize> {
self.parent_index
}
pub fn index(&self) -> usize {
self.index
}
}
impl<T: TreeItem> Tree<T> {
@ -305,6 +294,14 @@ impl<T> Tree<T> {
.collect();
self.regenerate_index()
}
pub fn parent_index(&self) -> Option<usize> {
self.parent_index
}
pub fn index(&self) -> usize {
self.index
}
}
pub struct TreeView<T: TreeItem> {
@ -327,8 +324,7 @@ pub struct TreeView<T: TreeItem> {
#[allow(clippy::type_complexity)]
pre_render: Option<Box<dyn Fn(&mut Self, Rect) + 'static>>,
#[allow(clippy::type_complexity)]
on_opened_fn:
Option<Box<dyn FnMut(&mut T, &mut Context, &mut T::Params) -> TreeOp<T> + 'static>>,
on_opened_fn: Option<Box<dyn FnMut(&mut T, &mut Context, &mut T::Params) -> TreeOp + 'static>>,
#[allow(clippy::type_complexity)]
on_folded_fn: Option<Box<dyn FnMut(&mut T, &mut Context, &mut T::Params) + 'static>>,
#[allow(clippy::type_complexity)]
@ -355,21 +351,13 @@ impl<T: TreeItem> TreeView<T> {
}
}
pub fn replace_with_new_items(&mut self, items: Vec<T>) {
todo!()
// let old = std::mem::replace(self, Self::new(vec_to_tree(items)));
// self.on_opened_fn = old.on_opened_fn;
// self.on_folded_fn = old.on_folded_fn;
// self.tree_symbol_style = old.tree_symbol_style;
}
pub fn build_tree(root: T, items: Vec<T>) -> Self {
Self::new(root, vec_to_tree(items))
}
pub fn with_enter_fn<F>(mut self, f: F) -> Self
where
F: FnMut(&mut T, &mut Context, &mut T::Params) -> TreeOp<T> + 'static,
F: FnMut(&mut T, &mut Context, &mut T::Params) -> TreeOp + 'static,
{
self.on_opened_fn = Some(Box::new(f));
self
@ -464,7 +452,7 @@ impl<T: TreeItem> TreeView<T> {
}
}
fn go_to_children(&mut self, cx: &mut Context) -> Result<()> {
fn go_to_children(&mut self) -> Result<()> {
let current = self.current_mut();
if current.is_opened {
self.selected += 1;
@ -530,18 +518,6 @@ impl<T: TreeItem> TreeView<T> {
let mut f = || {
let current = &mut self.get_mut(selected_index);
match on_open_fn(&mut current.item, cx, params) {
TreeOp::Restore => {
panic!();
// let inserts = std::mem::take(&mut current.folded);
// let _: Vec<_> = self
// .items
// .splice(selected_index + 1..selected_index + 1, inserts)
// .collect();
return;
}
TreeOp::InsertChild(items) => {
items;
}
TreeOp::GetChildsAndInsert => {
let items = match current.item.get_children() {
Ok(items) => items,
@ -550,33 +526,12 @@ impl<T: TreeItem> TreeView<T> {
current.is_opened = true;
current.children = vec_to_tree(items);
}
TreeOp::ReplaceTree { root, children } => {
self.tree = Tree::new(root, vec_to_tree(children));
self.selected = 0;
self.winline = 0;
}
TreeOp::Noop => {}
};
// current.folded = vec![];
// let inserts = vec_to_tree(items, current.level + 1);
// let _: Vec<_> = self
// .items
// .splice(selected_index + 1..selected_index + 1, inserts)
// .collect();
};
f();
self.regenerate_index();
self.on_opened_fn = Some(on_open_fn)
} else {
panic!();
self.get_mut(selected_index).children = vec![];
// let current = &mut self.items[selected_index];
// let inserts = std::mem::take(&mut current.folded);
// let _: Vec<_> = self
// .items
// .splice(selected_index + 1..selected_index + 1, inserts)
// .collect();
}
}
@ -589,7 +544,7 @@ impl<T: TreeItem> TreeView<T> {
}
}
pub fn search_next(&mut self, cx: &mut Context, s: &str, params: &mut T::Params) {
pub fn search_next(&mut self, s: &str) {
let skip = std::cmp::max(2, self.save_view.0 + 1);
self.selected = self
.tree
@ -599,7 +554,7 @@ impl<T: TreeItem> TreeView<T> {
self.winline = (self.save_view.1 + self.selected).saturating_sub(self.save_view.0);
}
pub fn search_previous(&mut self, cx: &mut Context, s: &str, params: &mut T::Params) {
pub fn search_previous(&mut self, s: &str) {
let take = self.save_view.0;
self.selected = self
.tree
@ -881,69 +836,6 @@ impl<T: TreeItem> TreeView<T> {
},
);
}
// let mut text = elem.item.text(cx, skip + index == self.selected, params);
// for (index, elem) in iter {
// let row = index as u16;
// let mut area = Rect::new(area.x, area.y + row, area.width, 1);
// let indent = if elem.level > 0 {
// if index + skip != last_item_index {
// format!("{}├─", "│ ".repeat(elem.level - 1))
// } else {
// format!("└─{}", "┴─".repeat(elem.level - 1))
// }
// } else {
// "".to_string()
// };
// let indent_len = indent.chars().count();
// if indent_len > self.col {
// let indent: String = indent.chars().skip(self.col).collect();
// if !indent.is_empty() {
// surface.set_stringn(area.x, area.y, &indent, area.width as usize, style);
// area = area.clip_left(indent.width() as u16);
// }
// };
// let mut start_index = self.col.saturating_sub(indent_len);
// let mut text = elem.item.text(cx, skip + index == self.selected, params);
// self.max_len = self.max_len.max(text.width() + indent.len());
// for span in text.0.iter_mut() {
// if area.width == 0 {
// return;
// }
// if start_index == 0 {
// surface.set_span(area.x, area.y, span, area.width);
// area = area.clip_left(span.width() as u16);
// } else {
// let span_width = span.width();
// if start_index > span_width {
// start_index -= span_width;
// } else {
// let content: String = span
// .content
// .chars()
// .filter(|c| {
// if start_index > 0 {
// start_index = start_index.saturating_sub(c.to_string().width());
// false
// } else {
// true
// }
// })
// .collect();
// surface.set_string_truncated(
// area.x,
// area.y,
// &content,
// area.width as usize,
// |_| span.style,
// false,
// false,
// );
// start_index = 0
// }
// }
// }
// }
}
pub fn handle_event(
@ -976,7 +868,7 @@ impl<T: TreeItem> TreeView<T> {
}));
}
key!('h') => self.go_to_parent(),
key!('l') => match self.go_to_children(cx) {
key!('l') => match self.go_to_children() {
Ok(_) => {}
Err(err) => cx.editor.set_error(err.to_string()),
},
@ -998,7 +890,7 @@ impl<T: TreeItem> TreeView<T> {
}
impl<T: TreeItem + Clone> TreeView<T> {
pub fn filter(&mut self, s: &str, cx: &mut Context, params: &mut T::Params) {
pub fn filter(&mut self, s: &str) {
if s.is_empty() {
self.restore_recycle();
return;
@ -1079,7 +971,9 @@ fn index_elems<T>(parent_index: usize, elems: Vec<Tree<T>>) -> Vec<Tree<T>> {
mod test_tree {
use helix_core::movement::Direction;
use super::{index_elems, Tree};
use crate::ui::TreeItem;
use super::Tree;
#[test]
fn test_indexs_elems() {
@ -1232,41 +1126,91 @@ mod test_tree {
#[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(
".cargo",
MyItem(false, ".cargo"),
vec![
Tree::new("spam", vec![Tree::new("Cargo.toml", vec![])]),
Tree::new("Cargo.toml", vec![Tree::new("pam", vec![])]),
Tree::new("hello", 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.to_lowercase().contains("cargo"));
let result = Tree::filter(&tree, &|item| item.1.to_lowercase().contains("cargo"));
assert_eq!(
result,
Some(Tree::new(
".cargo",
MyItem(false, ".cargo"),
vec![
Tree::new("spam", vec![Tree::new("Cargo.toml", vec![])]),
Tree::new("Cargo.toml", 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.to_lowercase().contains("pam"));
let result = Tree::filter(&tree, &|item| item.1.to_lowercase().contains("pam"));
assert_eq!(
result,
Some(Tree::new(
".cargo",
MyItem(false, ".cargo"),
vec![
Tree::new("spam", vec![]),
Tree::new("Cargo.toml", vec![Tree::new("pam", 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.to_lowercase().contains("helix"));
assert_eq!(result, None)
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]

Loading…
Cancel
Save