refactored display for decoupling

main
nick 2024-10-05 20:58:12 -04:00
parent f4a3a46c71
commit 9c8a5e9348
1 changed files with 40 additions and 54 deletions

View File

@ -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,6 +191,42 @@ 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()
+ &current.name
+ if current.is_file {
"\n"
} else {
"/\n"
};
Some(result)
}
)
}
}
impl Pane for Directory {
@ -221,57 +257,7 @@ impl Pane for Directory {
}
fn display(&self, output: OutputSink, area: Rect) {
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(&current.name);
if !current.is_file {
result.push('/');
}
result.push('\n');
}
let rows = result
.lines()
let rows = self.display_lines()
.enumerate()
.map(|(i, s)| {
let row = ListItem::new(s);