Compare commits
No commits in common. "9c8a5e93481c4a56462dce47d8f0cce3df6dfda7" and "5d62329e422d7a73aafe266d9b942d742e274d17" have entirely different histories.
9c8a5e9348
...
5d62329e42
|
@ -92,7 +92,7 @@ impl Directory {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn delete(&self) -> Result<(), Error> {
|
||||
if self.selected().is_file {
|
||||
remove_file(self.path())
|
||||
|
@ -109,11 +109,11 @@ impl Directory {
|
|||
let idx = self.selection();
|
||||
&mut self.dirs[idx]
|
||||
}
|
||||
|
||||
|
||||
pub const fn selection(&self) -> usize {
|
||||
self.selection as usize
|
||||
}
|
||||
|
||||
|
||||
pub fn update_navigation(&mut self, key: KeyCode) -> Result<Message, Error> {
|
||||
match key {
|
||||
KeyCode::Char(c) => {
|
||||
|
@ -191,42 +191,6 @@ impl Directory {
|
|||
Ok(Message::Nothing)
|
||||
}
|
||||
|
||||
fn display_lines(&self) -> impl Iterator<Item = String> + '_ {
|
||||
let iter = self.dirs.iter().enumerate();
|
||||
|
||||
iter.scan(
|
||||
Vec::new(),
|
||||
|indent_parts, (i, current)| {
|
||||
let is_last_at_this_depth = is_last_at_this_depth(&self.dirs[i+1..], current.depth);
|
||||
let (new_part, continue_part) = if is_last_at_this_depth {
|
||||
(TreePart::Last, TreePart::Blank)
|
||||
} else {
|
||||
(TreePart::First, TreePart::Wait)
|
||||
};
|
||||
|
||||
if i == 0 { return Some(current.name.to_owned() + "/") }
|
||||
|
||||
if current.depth as usize > indent_parts.len() {
|
||||
indent_parts.push(continue_part);
|
||||
} else {
|
||||
indent_parts[current.depth as usize-1] = continue_part;
|
||||
}
|
||||
|
||||
let result = indent_parts[0 .. current.depth as usize - 1]
|
||||
.iter()
|
||||
.fold(String::new(), |result, t| result + t.display())
|
||||
+ new_part.display()
|
||||
+ ¤t.name
|
||||
+ if current.is_file {
|
||||
"\n"
|
||||
} else {
|
||||
"/\n"
|
||||
};
|
||||
|
||||
Some(result)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Pane for Directory {
|
||||
|
@ -257,7 +221,57 @@ impl Pane for Directory {
|
|||
}
|
||||
|
||||
fn display(&self, output: OutputSink, area: Rect) {
|
||||
let rows = self.display_lines()
|
||||
let mut iter = self.dirs.iter().enumerate();
|
||||
let Some((_, init)) = iter.by_ref()
|
||||
.next()
|
||||
else { return };
|
||||
|
||||
let mut indent_parts = Vec::new();
|
||||
let mut result = init.name.clone() + "/\n";
|
||||
|
||||
for (i, current) in iter {
|
||||
// first, determine if there is another item at this depth.
|
||||
// that decides what art we use
|
||||
let is_last_at_this_depth = is_last_at_this_depth(&self.dirs[i+1..], current.depth);
|
||||
let (new_part, continue_part) = if is_last_at_this_depth {
|
||||
(TreePart::Last, TreePart::Blank)
|
||||
} else {
|
||||
(TreePart::First, TreePart::Wait)
|
||||
};
|
||||
|
||||
// setting indent_parts is important.
|
||||
// indent_parts[i] is the indent for depth i,
|
||||
// and it needs to be set to what we decided the `continue_part`
|
||||
// needs to be.
|
||||
// The if branch is for when we exceed the current depth and must
|
||||
// add a new indent part. the else branch is when we already
|
||||
// defined a branch at this point, and we do need to update it
|
||||
// every time
|
||||
// TODO: figure out why
|
||||
if current.depth as usize > indent_parts.len() {
|
||||
indent_parts.push(continue_part);
|
||||
} else {
|
||||
indent_parts[current.depth as usize-1] = continue_part;
|
||||
}
|
||||
|
||||
// I have inlined this to avoid making extra strings
|
||||
// because I believe it is less efficient
|
||||
indent_parts[0 .. current.depth as usize - 1]
|
||||
.iter()
|
||||
.copied()
|
||||
.map(TreePart::display)
|
||||
.for_each(|s| result += s);
|
||||
|
||||
result.push_str(new_part.display());
|
||||
result.push_str(¤t.name);
|
||||
if !current.is_file {
|
||||
result.push('/');
|
||||
}
|
||||
result.push('\n');
|
||||
}
|
||||
|
||||
let rows = result
|
||||
.lines()
|
||||
.enumerate()
|
||||
.map(|(i, s)| {
|
||||
let row = ListItem::new(s);
|
||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -14,7 +14,7 @@ use terminal::Terminal;
|
|||
use pane::prelude::*;
|
||||
|
||||
use std::fs::{remove_file, OpenOptions};
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::io::Error;
|
||||
|
||||
use anyhow::{Result as AnyResult, Error as AnyError};
|
||||
use clap::Parser;
|
||||
|
@ -32,22 +32,16 @@ fn main() -> AnyResult<()> {
|
|||
.create_new(true)
|
||||
.open(LOG_FILE)
|
||||
.map_err(|e| {
|
||||
let kind = e.kind();
|
||||
let result = AnyError::from(e).context(LOG_FILE);
|
||||
if kind == ErrorKind::AlreadyExists {
|
||||
result.context(LOG_EXISTS_MSG)
|
||||
} else {
|
||||
result
|
||||
}
|
||||
<Error as Into<AnyError>>::into(e).context(LOG_FILE).context(LOG_EXISTS_MSG)
|
||||
})?;
|
||||
|
||||
let _redirect = Redirect::stderr(target)?;
|
||||
|
||||
let result = do_tui(args);
|
||||
do_tui(args)?;
|
||||
|
||||
remove_file(LOG_FILE)?;
|
||||
|
||||
result.map_err(Into::into)
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn do_tui(args: Args) -> Result<(), Error> {
|
||||
|
|
Loading…
Reference in New Issue