adjusted explorer to new helix code

imgbot
Roland Singer 2 years ago
commit 92ebab74b5

@ -26,6 +26,27 @@ macro_rules! get_theme {
};
}
const ICONS: &'static [&'static str] =
&["", "", "", "", "", "ﰟ", "", "", "", "ﯤ", "", "ﬥ"];
const ICONS_EXT: &'static [&'static str] = &[
".rs", ".md", ".js", ".c", ".png", ".svg", ".css", ".html", ".lua", ".ts", ".py", ".json",
];
const ICONS_COLORS: &'static [helix_view::theme::Color] = &[
helix_view::theme::Color::Rgb(227, 134, 84),
helix_view::theme::Color::LightCyan,
helix_view::theme::Color::Yellow,
helix_view::theme::Color::Blue,
helix_view::theme::Color::Yellow,
helix_view::theme::Color::Yellow,
helix_view::theme::Color::Green,
helix_view::theme::Color::Blue,
helix_view::theme::Color::Red,
helix_view::theme::Color::Blue,
helix_view::theme::Color::Red,
];
#[derive(Debug, Clone, Copy, PartialEq)]
enum FileType {
File,
@ -39,18 +60,24 @@ enum FileType {
#[derive(Debug, Clone)]
struct FileInfo {
file_type: FileType,
expanded: bool,
path: PathBuf,
}
impl FileInfo {
fn new(path: PathBuf, file_type: FileType) -> Self {
Self { path, file_type }
Self {
path,
file_type,
expanded: false,
}
}
fn root(path: PathBuf) -> Self {
Self {
file_type: FileType::Root,
path,
expanded: true,
}
}
@ -59,6 +86,7 @@ impl FileInfo {
Self {
file_type: FileType::Parent,
path: p.to_path_buf(),
expanded: false,
}
}
@ -159,6 +187,7 @@ impl TreeItem for FileInfo {
Self {
file_type,
path: self.path.join(entry.file_name()),
expanded: false,
}
})
})
@ -167,6 +196,7 @@ impl TreeItem for FileInfo {
ret.push(Self {
path: self.path.clone(),
file_type: FileType::Placeholder,
expanded: false,
})
}
Ok(ret)
@ -179,6 +209,33 @@ impl TreeItem for FileInfo {
self.get_text().contains(s)
}
}
fn icon(&self) -> Option<(&'static str, &'static helix_view::theme::Color)> {
return match self.file_type {
FileType::Dir => {
if self.expanded {
//Some(("", &helix_view::theme::Color::Yellow))
Some(("", &helix_view::theme::Color::Yellow))
} else {
// Some(("", &helix_view::theme::Color::Yellow))
Some(("", &helix_view::theme::Color::Yellow))
}
}
FileType::File => {
for (i, ext) in ICONS_EXT.iter().enumerate() {
if self.get_text().ends_with(ext) {
let color = ICONS_COLORS
.iter()
.nth(i)
.unwrap_or(&helix_view::theme::Color::Blue);
return ICONS.iter().nth(i).map(|c| (*c, color));
}
}
return Some(("", &helix_view::theme::Color::LightBlue));
}
_ => None,
};
}
}
// #[derive(Default, Debug, Clone)]
@ -254,7 +311,9 @@ impl Explorer {
let current_root = std::env::current_dir().unwrap_or_else(|_| "./".into());
let items = Self::get_items(current_root.clone(), cx)?;
Ok(Self {
tree: Tree::build_tree(items).with_enter_fn(Self::toggle_current),
tree: Tree::build_tree(items)
.with_enter_fn(Self::toggle_current)
.with_folded_fn(Self::fold_current),
state: State::new(true, current_root),
repeat_motion: None,
prompt: None,
@ -266,8 +325,9 @@ impl Explorer {
let current_root = std::env::current_dir().unwrap_or_else(|_| "./".into());
let parent = FileInfo::parent(&current_root);
let root = FileInfo::root(current_root.clone());
let mut tree =
Tree::build_from_root(root, usize::MAX / 2)?.with_enter_fn(Self::toggle_current);
let mut tree = Tree::build_from_root(root, usize::MAX / 2)?
.with_enter_fn(Self::toggle_current)
.with_folded_fn(Self::fold_current);
tree.insert_current_level(parent);
Ok(Self {
tree,
@ -319,7 +379,12 @@ impl Explorer {
if item.file_type == FileType::Placeholder {
return;
}
let head_area = render_block(area.clip_bottom(area.height - 2), surface, Borders::BOTTOM);
let head_area = render_block(
area.clip_bottom(area.height - 2),
surface,
Borders::BOTTOM,
None,
);
let path_str = format!("{}", item.path.display());
surface.set_stringn(
head_area.x,
@ -434,6 +499,12 @@ impl Explorer {
));
}
fn fold_current(item: &mut FileInfo, _cx: &mut Context, _state: &mut State) {
if item.path.is_dir() {
item.expanded = false;
}
}
fn toggle_current(
item: &mut FileInfo,
cx: &mut Context,
@ -453,7 +524,7 @@ impl Explorer {
}
};
if meta.is_file() {
if let Err(e) = cx.editor.open(&item.path, Action::Replace) {
if let Err(e) = cx.editor.open(&item.path.clone(), Action::Replace) {
cx.editor.set_error(format!("{e}"));
}
state.focus = false;
@ -461,6 +532,7 @@ impl Explorer {
}
if item.path.is_dir() {
item.expanded = true;
if cx.editor.config().explorer.is_list() || item.file_type == FileType::Parent {
match Self::get_items(item.path.clone(), cx) {
Ok(items) => {
@ -481,19 +553,28 @@ impl Explorer {
let background = cx.editor.theme.get("ui.background");
let column_width = cx.editor.config().explorer.column_width as u16;
surface.clear_with(area, background);
let area = render_block(area, surface, Borders::ALL);
let area = render_block(area, surface, Borders::ALL, None);
let mut preview_area = area.clip_left(column_width + 1);
if let Some((_, prompt)) = self.prompt.as_mut() {
let area = preview_area.clip_bottom(2);
let promp_area =
render_block(preview_area.clip_top(area.height), surface, Borders::TOP);
let promp_area = render_block(
preview_area.clip_top(area.height),
surface,
Borders::TOP,
None,
);
prompt.render(promp_area, surface, cx);
preview_area = area;
}
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,
None,
);
self.tree.render(list_area, surface, cx, &mut self.state);
}
@ -502,14 +583,21 @@ impl Explorer {
let side_area = area
.with_width(area.width.min(config.column_width as u16 + 2))
.clip_bottom(1);
let background = cx.editor.theme.get("ui.background");
let background = cx.editor.theme.get("ui.statusline");
surface.clear_with(side_area, background);
let preview_area = area.clip_left(side_area.width).clip_bottom(2);
let prompt_area = area.clip_top(side_area.height);
let list_area =
render_block(side_area.clip_left(1), surface, Borders::RIGHT).clip_bottom(1);
let border_style = cx.editor.theme.get("ui.explorer.border");
let list_area = render_block(
side_area.clip_left(1),
surface,
Borders::RIGHT,
Some(border_style),
)
.clip_bottom(1);
self.tree.render(list_area, surface, cx, &mut self.state);
{
@ -543,7 +631,7 @@ impl Explorer {
}
let area = Rect::new(preview_area.x, y, width, height);
surface.clear_with(area, background);
let area = render_block(area, surface, Borders::all());
let area = render_block(area, surface, Borders::all(), None);
self.render_preview(area, surface, cx.editor);
}
@ -757,7 +845,9 @@ impl Component for Explorer {
match Self::get_items(p.to_path_buf(), cx) {
Ok(items) => {
self.state.current_root = p.to_path_buf();
self.tree = Tree::build_tree(items).with_enter_fn(Self::toggle_current);
self.tree = Tree::build_tree(items)
.with_enter_fn(Self::toggle_current)
.with_folded_fn(Self::fold_current);
}
Err(e) => cx.editor.set_error(format!("{e}")),
}
@ -859,8 +949,17 @@ fn get_preview(p: impl AsRef<Path>, max_line: usize) -> Result<Vec<String>> {
.collect())
}
fn render_block(area: Rect, surface: &mut Surface, borders: Borders) -> Rect {
let block = Block::default().borders(borders);
fn render_block(
area: Rect,
surface: &mut Surface,
borders: Borders,
border_style: Option<helix_view::theme::Style>,
) -> Rect {
let mut block = Block::default().borders(borders);
if let Some(style) = border_style {
block = block.border_style(style);
}
//let block = Block::default();
let inner = block.inner(area);
block.render(area, surface);
inner

@ -20,6 +20,7 @@ pub trait TreeItem: Sized {
fn text(&self, cx: &mut Context, selected: bool, params: &mut Self::Params) -> Spans;
fn is_child(&self, other: &Self) -> bool;
fn cmp(&self, other: &Self) -> Ordering;
fn icon(&self) -> Option<(&'static str, &'static helix_view::theme::Color)>;
fn filter(&self, cx: &mut Context, s: &str, params: &mut Self::Params) -> bool {
self.text(cx, false, params)
@ -178,7 +179,7 @@ impl<T: TreeItem> Tree<T> {
col: 0,
max_len: 0,
count: 0,
tree_symbol_style: "ui.text".into(),
tree_symbol_style: "ui.explorer.guide".into(),
pre_render: None,
on_opened_fn: None,
on_folded_fn: None,
@ -471,6 +472,7 @@ impl<T: TreeItem> Tree<T> {
self.max_len = 0;
self.row = std::cmp::min(self.row, area.height.saturating_sub(1) as usize);
let style = cx.editor.theme.get(&self.tree_symbol_style);
let folder_style = cx.editor.theme.get("special");
let last_item_index = self.items.len().saturating_sub(1);
let skip = self.selected.saturating_sub(self.row);
let iter = self
@ -484,9 +486,9 @@ impl<T: TreeItem> Tree<T> {
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))
format!("{}", "│ ".repeat(elem.level - 1))
} else {
format!("└─{}", "┴─".repeat(elem.level - 1))
format!("{}", "".repeat(elem.level - 1))
}
} else {
"".to_string()
@ -502,14 +504,20 @@ impl<T: TreeItem> Tree<T> {
};
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());
self.max_len = self.max_len.max(text.width() + indent.len() - 2);
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);
let mut icon_offset = 0;
if let Some((icon, color)) = elem.item.icon() {
let style = folder_style.fg(*color);
surface.set_string(area.x, area.y, icon, style);
icon_offset = 2;
}
surface.set_span(area.x + icon_offset, area.y, span, area.width - icon_offset);
area = area.clip_left((span.width() - icon_offset as usize) as u16);
} else {
let span_width = span.width();
if start_index > span_width {
@ -527,10 +535,13 @@ impl<T: TreeItem> Tree<T> {
}
})
.collect();
let mut cont = String::new();
cont.push_str("");
cont.push_str(&content);
surface.set_string_truncated(
area.x,
area.y,
&content,
&cont,
area.width as usize,
|_| span.style,
false,

@ -78,6 +78,12 @@
"ui.explorer.focus" = { modifiers = ["reversed"] }
"ui.explorer.unfocus" = { bg = "bg3" }
"ui.explorer.file" = { fg = "fg" }
"ui.explorer.dir" = { fg = "blue" }
"ui.explorer.exe" = { fg = "fg" }
"ui.explorer.focus" = { modifiers = ["reversed"] }
"ui.explorer.unfocus" = { bg = "bg3" }
[palette]
bg0 = "#323437"

Loading…
Cancel
Save