now actually modifies the filesystem. renaming files tbd

main
nick 2024-10-02 16:04:11 -04:00
parent 4f9b52151c
commit 15a2b700cd
3 changed files with 80 additions and 17 deletions

View File

@ -1,6 +1,10 @@
mod display; mod display;
mod item; mod item;
use std::fs::{remove_dir_all, remove_file, DirBuilder, File};
use std::io::Error;
use std::path::PathBuf;
use tui::widgets::{Block, Borders, List, ListItem}; use tui::widgets::{Block, Borders, List, ListItem};
use tui::style::{Color, Style}; use tui::style::{Color, Style};
use tui::layout::Rect; use tui::layout::Rect;
@ -17,12 +21,37 @@ pub struct Directory {
editing: bool, editing: bool,
} }
impl Directory { impl Directory {
pub fn new(root: String) -> Self { pub fn new(root: String) -> Result<Self, Error> {
Self { DirBuilder::new()
.recursive(true)
.create(&root)?;
Ok(Self {
dirs: vec![Item::new(root, 0, false)], dirs: vec![Item::new(root, 0, false)],
selection: 0, selection: 0,
editing: false, editing: false,
} })
}
pub fn path(&self) -> PathBuf {
let s = self.selected();
let init = (PathBuf::from(s.name.as_str()), s.depth);
let (result, _) = self.dirs[0..=self.selection()]
.iter()
.rev()
.fold(
init,
|(mut path, mut depth), d| {
if d.depth < depth {
path = PathBuf::from(&d.name).join(path);
depth = d.depth;
}
(path, depth)
}
);
result
} }
pub fn select_prev(&mut self) { pub fn select_prev(&mut self) {
@ -47,9 +76,30 @@ impl Directory {
}; };
let new = Item::new(name, depth, is_file); let new = Item::new(name, depth, is_file);
self.dirs.insert(self.selection()+1, new);
self.selection += 1;
self.dirs.insert(self.selection(), new);
}
fn create(&self) -> Result<(), Error> {
if self.selected().is_file {
File::create(self.path())?;
} else {
DirBuilder::new()
.recursive(true)
.create(self.path())?;
}
Ok(())
} }
fn delete(&self) -> Result<(), Error> {
if self.selected().is_file {
remove_file(self.path())
} else {
remove_dir_all(self.path())
}
}
fn selected(&self) -> &Item { fn selected(&self) -> &Item {
&self.dirs[self.selection()] &self.dirs[self.selection()]
} }
@ -69,12 +119,10 @@ impl Directory {
match c { match c {
'f' | 'F' => { 'f' | 'F' => {
self.insert(String::new(), true); self.insert(String::new(), true);
self.select_next();
self.editing = true; self.editing = true;
}, },
'd' | 'D' => { 'd' | 'D' => {
self.insert(String::new(), false); self.insert(String::new(), false);
self.select_next();
self.editing = true; self.editing = true;
}, },
'x' | 'X' => { 'x' | 'X' => {
@ -89,12 +137,22 @@ impl Directory {
self.editing = true; self.editing = true;
}, },
KeyCode::Esc => return Message::Exit, KeyCode::Esc => return Message::Exit,
KeyCode::Backspace => { KeyCode::Backspace if self.selected().depth > 0 => {
self.delete().unwrap();
if self.selected().is_file { if self.selected().is_file {
self.dirs.remove(self.selection()); self.dirs.remove(self.selection());
if self.selection() == self.dirs.len() { } else {
self.selection -= 1; let target_depth = self.selected().depth;
}
let end = (self.selection()+1 .. self.dirs.len())
.find(|&i| self.dirs[i].depth <= target_depth)
.unwrap_or(self.dirs.len());
self.dirs.drain(self.selection()..end);
}
if self.selection() >= self.dirs.len() {
self.selection -= 1;
} }
} }
_ => (), _ => (),
@ -107,9 +165,12 @@ impl Directory {
match key { match key {
KeyCode::Char(c) => self.selected_mut().name.push(c), KeyCode::Char(c) => self.selected_mut().name.push(c),
KeyCode::Enter | KeyCode::Esc if !self.selected().name.is_empty() => { KeyCode::Enter | KeyCode::Esc if !self.selected().name.is_empty() => {
self.create().unwrap();
self.editing = false; self.editing = false;
}, },
KeyCode::Backspace => { self.selected_mut().name.pop(); }, KeyCode::Backspace => {
self.selected_mut().name.pop();
},
_ => (), _ => (),
} }

View File

@ -17,7 +17,7 @@ fn main() -> Result<(), Error> {
let mut terminal = Terminal::new()?; let mut terminal = Terminal::new()?;
let area = terminal.size()?; let area = terminal.size()?;
let mut state = State::new(area); let mut state = State::new(area)?;
loop { loop {
state.render(&mut terminal)?; state.render(&mut terminal)?;

View File

@ -22,13 +22,13 @@ pub struct State {
command: Option<Either<Command, CommandOutput>> command: Option<Either<Command, CommandOutput>>
} }
impl State { impl State {
pub fn new(area: Rect) -> Self { pub fn new(area: Rect) -> Result<Self, Error> {
let dir = Directory::new("root".into()); let dir = Directory::new("root".into())?;
Self { Ok(Self {
dir, dir,
size: area, size: area,
command: None, command: None,
} })
} }
pub fn render(&self, terminal: &mut Terminal) -> Result<(), Error> { pub fn render(&self, terminal: &mut Terminal) -> Result<(), Error> {
@ -112,11 +112,13 @@ impl State {
else { unsafe { unreachable_unchecked() } }; else { unsafe { unreachable_unchecked() } };
let mut iter = cmd.buf() let mut iter = cmd.buf()
.split(' '); .split(' ')
.filter(|s| !s.is_empty());
let prog_name = iter.next().unwrap(); let prog_name = iter.next().unwrap();
let output = Executable::new(prog_name) let output = Executable::new(prog_name)
.args(iter) .args(iter)
.arg(self.dir.path())
.output(); .output();
let command_output = CommandOutput::new(output.map(|o| o.stdout)); let command_output = CommandOutput::new(output.map(|o| o.stdout));