[tui] Add Explorer widget for left panel.
This commit is contained in:
parent
fac6ea6bcd
commit
b65565adfa
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -230,6 +230,8 @@ dependencies = [
|
|||||||
"ratatui",
|
"ratatui",
|
||||||
"structopt",
|
"structopt",
|
||||||
"syntect",
|
"syntect",
|
||||||
|
"tui-tree-widget",
|
||||||
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1908,6 +1910,17 @@ dependencies = [
|
|||||||
"time-core",
|
"time-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tui-tree-widget"
|
||||||
|
version = "0.24.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "deca119555009eee2e0cfb9c020f39f632444dc4579918d5fc009d51d75dff92"
|
||||||
|
dependencies = [
|
||||||
|
"ratatui-core",
|
||||||
|
"ratatui-widgets",
|
||||||
|
"unicode-width 0.2.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.19.0"
|
version = "1.19.0"
|
||||||
|
|||||||
@ -13,6 +13,8 @@ syntect = "5.2.0"
|
|||||||
structopt = "0.3.26"
|
structopt = "0.3.26"
|
||||||
ratatui = "0.30.0"
|
ratatui = "0.30.0"
|
||||||
anyhow = "1.0.100"
|
anyhow = "1.0.100"
|
||||||
|
tui-tree-widget = "0.24.0"
|
||||||
|
uuid = { version = "1.19.0", features = ["v4"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
# The link_qt_object_files feature is required for statically linking Qt 6.
|
# The link_qt_object_files feature is required for statically linking Qt 6.
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
pub mod app;
|
pub mod app;
|
||||||
|
mod explorer;
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
|
|||||||
@ -8,14 +8,18 @@ use ratatui::widgets::{Block, Borders, Padding, Paragraph, Tabs, Wrap};
|
|||||||
use ratatui::{DefaultTerminal, symbols};
|
use ratatui::{DefaultTerminal, symbols};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use crate::tui::explorer::Explorer;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct App<'a> {
|
pub struct App<'a> {
|
||||||
root_path: &'a std::path::Path,
|
explorer: Explorer<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> App<'a> {
|
impl<'a> App<'a> {
|
||||||
pub(crate) fn new(root_path: &'a std::path::Path) -> Self {
|
pub(crate) fn new(root_path: &'a std::path::Path) -> Self {
|
||||||
Self { root_path }
|
Self {
|
||||||
|
explorer: Explorer::new(root_path),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(mut self, mut terminal: DefaultTerminal) -> anyhow::Result<()> {
|
pub fn run(mut self, mut terminal: DefaultTerminal) -> anyhow::Result<()> {
|
||||||
@ -84,7 +88,7 @@ impl<'a> App<'a> {
|
|||||||
fn draw_terminal(self, area: Rect, buf: &mut Buffer) {
|
fn draw_terminal(self, area: Rect, buf: &mut Buffer) {
|
||||||
// TODO: Title should be detected shell name
|
// TODO: Title should be detected shell name
|
||||||
// TODO: Contents should be shell output
|
// TODO: Contents should be shell output
|
||||||
Paragraph::new("Terminal placeholder")
|
Paragraph::new("shaun@pc:~/Code/clide$ ")
|
||||||
.style(Style::default())
|
.style(Style::default())
|
||||||
.block(
|
.block(
|
||||||
Block::default()
|
Block::default()
|
||||||
@ -95,13 +99,6 @@ impl<'a> App<'a> {
|
|||||||
.wrap(Wrap { trim: false })
|
.wrap(Wrap { trim: false })
|
||||||
.render(area, buf);
|
.render(area, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_file_explorer(self, area: Rect, buf: &mut Buffer) {
|
|
||||||
Paragraph::new("File explorer placeholder")
|
|
||||||
.style(Style::default())
|
|
||||||
.block(Block::default().borders(Borders::ALL))
|
|
||||||
.render(area, buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Separate complex components into their own widgets.
|
// TODO: Separate complex components into their own widgets.
|
||||||
@ -138,7 +135,7 @@ impl<'a> Widget for App<'a> {
|
|||||||
self.draw_status(vertical[0], buf);
|
self.draw_status(vertical[0], buf);
|
||||||
self.draw_terminal(vertical[2], buf);
|
self.draw_terminal(vertical[2], buf);
|
||||||
|
|
||||||
self.draw_file_explorer(horizontal[0], buf);
|
self.explorer.draw(horizontal[0], buf);
|
||||||
|
|
||||||
self.draw_tabs(editor_layout[0], buf);
|
self.draw_tabs(editor_layout[0], buf);
|
||||||
self.draw_editor(editor_layout[1], buf);
|
self.draw_editor(editor_layout[1], buf);
|
||||||
|
|||||||
58
src/tui/explorer.rs
Normal file
58
src/tui/explorer.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::fs;
|
||||||
|
use ratatui::buffer::Buffer;
|
||||||
|
use ratatui::layout::Rect;
|
||||||
|
use ratatui::prelude::Style;
|
||||||
|
use ratatui::widgets::{Block, Borders, Widget};
|
||||||
|
use tui_tree_widget::{Tree, TreeItem};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Explorer<'a> {
|
||||||
|
root_path: &'a std::path::Path,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Explorer<'a> {
|
||||||
|
pub fn new(path: &'a std::path::Path) -> Self {
|
||||||
|
Explorer { root_path: path }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(self, area: Rect, buf: &mut Buffer) {
|
||||||
|
let tree_item = Self::build_tree_from_path(self.root_path.to_path_buf());
|
||||||
|
Tree::new(&tree_item.children())
|
||||||
|
.expect("Failed to build tree.")
|
||||||
|
.style(Style::default())
|
||||||
|
.block(Block::default().borders(Borders::ALL))
|
||||||
|
.render(area, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_tree_from_path(path: std::path::PathBuf) -> TreeItem<'static, String> {
|
||||||
|
let mut children = vec![];
|
||||||
|
if let Ok(entries) = fs::read_dir(&path) {
|
||||||
|
let mut paths = entries
|
||||||
|
.map(|res| res.map(|e| e.path()))
|
||||||
|
.collect::<Result<Vec<_>, std::io::Error>>()
|
||||||
|
.expect("");
|
||||||
|
paths.sort();
|
||||||
|
for path in paths {
|
||||||
|
if path.is_dir() {
|
||||||
|
children.push(Self::build_tree_from_path(path));
|
||||||
|
} else {
|
||||||
|
children.push(TreeItem::new_leaf(
|
||||||
|
Uuid::new_v4().to_string(),
|
||||||
|
path.file_name().unwrap().to_string_lossy().to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeItem::new(
|
||||||
|
Uuid::new_v4().to_string(),
|
||||||
|
path.file_name()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
children,
|
||||||
|
)
|
||||||
|
.expect("Failed to build tree from path.")
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user