|
|
@ -254,6 +254,7 @@ impl State {
|
|
|
|
|
|
|
|
|
|
|
|
pub struct Explorer {
|
|
|
|
pub struct Explorer {
|
|
|
|
tree: TreeView<FileInfo>,
|
|
|
|
tree: TreeView<FileInfo>,
|
|
|
|
|
|
|
|
show_help: bool,
|
|
|
|
state: State,
|
|
|
|
state: State,
|
|
|
|
prompt: Option<(PromptAction, Prompt)>,
|
|
|
|
prompt: Option<(PromptAction, Prompt)>,
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
|
@ -267,6 +268,7 @@ impl Explorer {
|
|
|
|
let current_root = std::env::current_dir().unwrap_or_else(|_| "./".into());
|
|
|
|
let current_root = std::env::current_dir().unwrap_or_else(|_| "./".into());
|
|
|
|
Ok(Self {
|
|
|
|
Ok(Self {
|
|
|
|
tree: Self::new_tree(current_root.clone())?,
|
|
|
|
tree: Self::new_tree(current_root.clone())?,
|
|
|
|
|
|
|
|
show_help: false,
|
|
|
|
state: State::new(true, current_root),
|
|
|
|
state: State::new(true, current_root),
|
|
|
|
repeat_motion: None,
|
|
|
|
repeat_motion: None,
|
|
|
|
prompt: None,
|
|
|
|
prompt: None,
|
|
|
@ -365,18 +367,39 @@ impl Explorer {
|
|
|
|
surface.set_stringn(
|
|
|
|
surface.set_stringn(
|
|
|
|
head_area.x,
|
|
|
|
head_area.x,
|
|
|
|
head_area.y,
|
|
|
|
head_area.y,
|
|
|
|
path_str,
|
|
|
|
if self.show_help {
|
|
|
|
|
|
|
|
"[HELP]".to_string()
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
path_str
|
|
|
|
|
|
|
|
},
|
|
|
|
head_area.width as usize,
|
|
|
|
head_area.width as usize,
|
|
|
|
get_theme!(editor.theme, "ui.explorer.dir", "ui.text"),
|
|
|
|
get_theme!(editor.theme, "ui.explorer.dir", "ui.text"),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
let body_area = area.clip_top(2);
|
|
|
|
let body_area = area.clip_top(2);
|
|
|
|
let style = editor.theme.get("ui.text");
|
|
|
|
let style = editor.theme.get("ui.text");
|
|
|
|
if let Ok(preview_content) = get_preview(&item.path, body_area.height as usize) {
|
|
|
|
let content = if self.show_help {
|
|
|
|
preview_content
|
|
|
|
vec![
|
|
|
|
|
|
|
|
"? Toggle help",
|
|
|
|
|
|
|
|
"a Add file",
|
|
|
|
|
|
|
|
"A Add folder",
|
|
|
|
|
|
|
|
"r Rename file/folder",
|
|
|
|
|
|
|
|
"d Delete file",
|
|
|
|
|
|
|
|
"/ Search",
|
|
|
|
|
|
|
|
"f Filter",
|
|
|
|
|
|
|
|
"[ Change root to parent",
|
|
|
|
|
|
|
|
"] Change root to current",
|
|
|
|
|
|
|
|
"R Refresh tree",
|
|
|
|
|
|
|
|
]
|
|
|
|
.into_iter()
|
|
|
|
.into_iter()
|
|
|
|
.enumerate()
|
|
|
|
.map(|s| s.to_string())
|
|
|
|
.for_each(|(row, line)| {
|
|
|
|
.chain(ui::tree::tree_view_help())
|
|
|
|
|
|
|
|
.collect()
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
get_preview(&item.path, body_area.height as usize)
|
|
|
|
|
|
|
|
.unwrap_or_else(|err| vec![err.to_string()])
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
content.into_iter().enumerate().for_each(|(row, line)| {
|
|
|
|
surface.set_stringn(
|
|
|
|
surface.set_stringn(
|
|
|
|
body_area.x,
|
|
|
|
body_area.x,
|
|
|
|
body_area.y + row as u16,
|
|
|
|
body_area.y + row as u16,
|
|
|
@ -386,7 +409,6 @@ impl Explorer {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn new_search_prompt(&mut self, search_next: bool) {
|
|
|
|
fn new_search_prompt(&mut self, search_next: bool) {
|
|
|
|
self.tree.save_view();
|
|
|
|
self.tree.save_view();
|
|
|
@ -596,7 +618,15 @@ impl Explorer {
|
|
|
|
self.render_preview(preview_area, surface, cx.editor);
|
|
|
|
self.render_preview(preview_area, surface, cx.editor);
|
|
|
|
|
|
|
|
|
|
|
|
let list_area = render_block(area.clip_right(preview_area.width), surface, Borders::RIGHT);
|
|
|
|
let list_area = render_block(area.clip_right(preview_area.width), surface, Borders::RIGHT);
|
|
|
|
self.tree.render(list_area, surface, cx, &mut self.state);
|
|
|
|
surface.set_stringn(
|
|
|
|
|
|
|
|
list_area.x,
|
|
|
|
|
|
|
|
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, &mut self.state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn render_embed(
|
|
|
|
pub fn render_embed(
|
|
|
@ -632,7 +662,15 @@ impl Explorer {
|
|
|
|
render_block(side_area.clip_right(1), surface, Borders::LEFT).clip_bottom(1)
|
|
|
|
render_block(side_area.clip_right(1), surface, Borders::LEFT).clip_bottom(1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
self.tree.render(list_area, surface, cx, &mut self.state);
|
|
|
|
surface.set_stringn(
|
|
|
|
|
|
|
|
list_area.x,
|
|
|
|
|
|
|
|
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, &mut self.state);
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let statusline = if self.is_focus() {
|
|
|
|
let statusline = if self.is_focus() {
|
|
|
@ -871,6 +909,10 @@ impl Explorer {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn toggle_help(&mut self) {
|
|
|
|
|
|
|
|
self.show_help = !self.show_help
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Component for Explorer {
|
|
|
|
impl Component for Explorer {
|
|
|
@ -915,7 +957,7 @@ impl Component for Explorer {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
key!('f') => self.new_filter_prompt(),
|
|
|
|
key!('f') => self.new_filter_prompt(),
|
|
|
|
key!('/') => self.new_search_prompt(true),
|
|
|
|
key!('/') => self.new_search_prompt(true),
|
|
|
|
key!('?') => self.new_search_prompt(false),
|
|
|
|
key!('?') => self.toggle_help(),
|
|
|
|
key!('a') => {
|
|
|
|
key!('a') => {
|
|
|
|
if let Err(error) = self.new_create_file_prompt() {
|
|
|
|
if let Err(error) = self.new_create_file_prompt() {
|
|
|
|
cx.editor.set_error(error.to_string())
|
|
|
|
cx.editor.set_error(error.to_string())
|
|
|
|