TUI #1
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -230,6 +230,8 @@ dependencies = [
|
||||
"ratatui",
|
||||
"structopt",
|
||||
"syntect",
|
||||
"tui-tree-widget",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1908,6 +1910,17 @@ dependencies = [
|
||||
"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]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
|
||||
@ -13,6 +13,8 @@ syntect = "5.2.0"
|
||||
structopt = "0.3.26"
|
||||
ratatui = "0.30.0"
|
||||
anyhow = "1.0.100"
|
||||
tui-tree-widget = "0.24.0"
|
||||
uuid = { version = "1.19.0", features = ["v4"] }
|
||||
|
||||
[build-dependencies]
|
||||
# The link_qt_object_files feature is required for statically linking Qt 6.
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
pub mod app;
|
||||
mod explorer;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
|
||||
@ -8,14 +8,18 @@ use ratatui::widgets::{Block, Borders, Padding, Paragraph, Tabs, Wrap};
|
||||
use ratatui::{DefaultTerminal, symbols};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::tui::explorer::Explorer;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct App<'a> {
|
||||
root_path: &'a std::path::Path,
|
||||
explorer: Explorer<'a>,
|
||||
}
|
||||
|
||||
impl<'a> App<'a> {
|
||||
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<()> {
|
||||
@ -84,7 +88,7 @@ impl<'a> App<'a> {
|
||||
fn draw_terminal(self, area: Rect, buf: &mut Buffer) {
|
||||
// TODO: Title should be detected shell name
|
||||
// TODO: Contents should be shell output
|
||||
Paragraph::new("Terminal placeholder")
|
||||
Paragraph::new("shaun@pc:~/Code/clide$ ")
|
||||
.style(Style::default())
|
||||
.block(
|
||||
Block::default()
|
||||
@ -95,13 +99,6 @@ impl<'a> App<'a> {
|
||||
.wrap(Wrap { trim: false })
|
||||
.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.
|
||||
@ -138,7 +135,7 @@ impl<'a> Widget for App<'a> {
|
||||
self.draw_status(vertical[0], 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_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