From a18cf073c7a0179cc9826ae6863af63e665529fc Mon Sep 17 00:00:00 2001 From: Penwing Date: Fri, 19 Jan 2024 17:20:15 +0100 Subject: [PATCH] tree open file --- src/main.rs | 84 +++++++++++++++++++++++++++++++++++++++--------- src/tools/mod.rs | 64 ++++++++++++++++++------------------ 2 files changed, 100 insertions(+), 48 deletions(-) diff --git a/src/main.rs b/src/main.rs index 480b38f..43840a8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,8 +4,11 @@ mod tools; use eframe::egui; use std::path::Path; use std::fs; +use std::io; +use std::env; const TERMINAL_HEIGHT : f32 = 200.0; +const RED : egui::Color32 = egui::Color32::from_rgb(235, 108, 99); fn main() -> Result<(), eframe::Error> { @@ -30,7 +33,7 @@ struct MyApp { language: String, code: String, command: String, - command_history: String, + command_history: Vec, } @@ -41,7 +44,7 @@ impl Default for MyApp { language: "rs".into(), code: "// write here".into(), command: "".into(), - command_history: "Welcome master".into(), + command_history: Vec::new(), } } } @@ -56,34 +59,55 @@ impl eframe::App for MyApp { } impl MyApp { - fn draw_tree_panel(&self, ctx: &egui::Context) { + fn draw_tree_panel(&mut self, ctx: &egui::Context) { egui::SidePanel::left("file_tree_panel").show(ctx, |ui| { - ui.heading("Bookshelves"); - let _ = tools::list_files(ui, Path::new("/home/penwing/Documents/")); + ui.heading("Bookshelf"); ui.separator(); + let _ = self.list_files(ui, Path::new("/home/penwing/Documents/")); + ui.separator(); + //~ tools::test(&self); }); } fn draw_terminal_panel(&mut self, ctx: &egui::Context) { egui::TopBottomPanel::bottom("terminal") - .exact_height(TERMINAL_HEIGHT.clone()) + .default_height(TERMINAL_HEIGHT.clone()) + .min_height(0.0) .show(ctx, |ui| { ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { ui.label(""); ui.horizontal(|ui| { let Self { command, .. } = self; - ui.label(">"); + ui.label(format!("{}>", env::current_dir().expect("Could not find Shell Environnment").file_name().expect("Could not get Shell Environnment Name").to_string_lossy().to_string())); let response = ui.add(egui::TextEdit::singleline(command).desired_width(f32::INFINITY).lock_focus(true)); if response.lost_focus() && ctx.input(|i| i.key_pressed(egui::Key::Enter)) { - self.command_history.push_str(&("\n".to_string() + &tools::run_command(self.command.clone()))); + self.command_history.push(tools::run_command(self.command.clone())); self.command = "".into(); response.request_focus(); } }); - egui::ScrollArea::vertical().show(ui, |ui| { - ui.separator(); - ui.label(self.command_history.clone()); + ui.separator(); + egui::ScrollArea::vertical().stick_to_bottom(true).show(ui, |ui| { + ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| { + ui.separator(); + ui.horizontal_wrapped(|ui| { + ui.spacing_mut().item_spacing.y = 0.0; + //ui.label(self.command_history.clone()); + for entry in &self.command_history { + ui.label(format!("{}> {}", entry.env, entry.command)); + ui.end_row(); + if entry.output != "" { + ui.label(&entry.output); + ui.end_row(); + } + if entry.error != "" { + ui.colored_label(RED, &entry.error); + ui.end_row(); + } + } + }); + }); }); }); }); @@ -93,11 +117,7 @@ impl MyApp { egui::CentralPanel::default().show(ctx, |ui| { if ui.button("Open fileā€¦").clicked() { if let Some(path) = rfd::FileDialog::new().pick_file() { - self.picked_path = Some(path.display().to_string()); - let file_path = Path::new(self.picked_path.as_deref().unwrap_or_default()); - self.code = fs::read_to_string(file_path).expect("Should have been able to read the file"); - self.language = file_path.to_str().unwrap().split('.').last().unwrap().into(); - println!("{}", self.language); + self.open_file(&path); } } @@ -130,5 +150,37 @@ impl MyApp { }); }); } + + fn list_files(&mut self, ui: &mut egui::Ui, path: &Path) -> io::Result<()> { + if let Some(name) = path.file_name() { + if path.is_dir() { + egui::CollapsingHeader::new(name.to_string_lossy()).show(ui, |ui| { + let mut paths: Vec<_> = fs::read_dir(&path).expect("Failed to read dir").map(|r| r.unwrap()).collect(); + + // Sort the vector using the custom sorting function + paths.sort_by(|a, b| tools::sort_directories_first(a, b)); + + for result in paths { + //let result = path_result.expect("Failed to get path"); + //let full_path = result.path(); + let _ = self.list_files(ui, &result.path()); + } + }); + } else { + //ui.label(name.to_string_lossy()); + if ui.button(name.to_string_lossy()).clicked() { + self.open_file(&path) + } + } + } + Ok(()) + } + + fn open_file(&mut self, path: &Path) { + self.picked_path = Some(path.display().to_string()); + let file_path = Path::new(self.picked_path.as_deref().unwrap_or_default()); + self.code = fs::read_to_string(file_path).expect("Not able to read the file"); + self.language = file_path.to_str().unwrap().split('.').last().unwrap().into(); + } } diff --git a/src/tools/mod.rs b/src/tools/mod.rs index b216161..1576591 100644 --- a/src/tools/mod.rs +++ b/src/tools/mod.rs @@ -1,51 +1,51 @@ -use eframe::egui; -use std::io; +//use eframe::egui; +//use std::io; use std::process::Command; use std::cmp::Ordering; -use std::path::Path; -use std::fs; +use std::env; +//use std::path::Path; +//use std::fs; +pub struct CommandEntry { + pub env : String, + pub command : String, + pub output : String, + pub error : String, +} + +impl Default for CommandEntry { + fn default() -> Self { + Self { + env: env::current_dir().expect("Could not find Shell Environnment").file_name().expect("Could not get Shell Environnment Name").to_string_lossy().to_string(), + command : "".into(), + output : "".into(), + error : "".into(), + } + } +} pub fn loaded() { println!("Tools loaded"); } -pub fn run_command(cmd : String) -> String { - let command = "> ".to_owned() + &cmd.clone() + "\n"; +pub fn run_command(cmd : String) -> CommandEntry { + let mut entry = CommandEntry::default(); let output = Command::new("sh") .arg("-c") - .arg(cmd) + .arg(cmd.clone()) .output() .expect("failed to execute process"); - (command + &String::from_utf8_lossy(&output.stdout)).to_string() + + entry.command = cmd; + entry.output = (&String::from_utf8_lossy(&output.stdout)).to_string(); + entry.error = (&String::from_utf8_lossy(&output.stdout)).to_string(); + + entry } -pub fn list_files(ui: &mut egui::Ui, path: &Path) -> io::Result<()> { - if let Some(name) = path.file_name() { - if path.is_dir() { - egui::CollapsingHeader::new(name.to_string_lossy()).show(ui, |ui| { - let mut paths: Vec<_> = fs::read_dir(&path).expect("Failed to read dir").map(|r| r.unwrap()).collect(); - - // Sort the vector using the custom sorting function - paths.sort_by(|a, b| sort_directories_first(a, b)); - - for result in paths { - //let result = path_result.expect("Failed to get path"); - //let full_path = result.path(); - let _ = list_files(ui, &result.path()); - } - }); - } else { - ui.label(name.to_string_lossy()); - } - } - Ok(()) -} - - -fn sort_directories_first(a: &std::fs::DirEntry, b: &std::fs::DirEntry) -> Ordering { +pub fn sort_directories_first(a: &std::fs::DirEntry, b: &std::fs::DirEntry) -> Ordering { let a_is_dir = a.path().is_dir(); let b_is_dir = b.path().is_dir();