diff options
-rw-r--r-- | src/common.rs | 21 | ||||
-rw-r--r-- | src/interactive/app.rs | 14 | ||||
-rw-r--r-- | src/interactive/widgets.rs | 34 | ||||
-rw-r--r-- | tests/interactive.rs | 27 |
4 files changed, 58 insertions, 38 deletions
diff --git a/src/common.rs b/src/common.rs index 11f7d7f..5aee23c 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,7 +1,8 @@ -use crate::interactive::{Tree, TreeIndex}; +use crate::interactive::{widgets::SortMode, EntryData, Tree, TreeIndex}; +use itertools::Itertools; use jwalk::WalkDir; -use std::fmt; -use std::path::Path; +use petgraph::Direction; +use std::{fmt, path::Path}; pub(crate) fn get_size_or_panic(tree: &Tree, node_idx: TreeIndex) -> u64 { tree.node_weight(node_idx) @@ -9,6 +10,20 @@ pub(crate) fn get_size_or_panic(tree: &Tree, node_idx: TreeIndex) -> u64 { .size } +pub(crate) fn sorted_entries( + tree: &Tree, + node_idx: TreeIndex, + sorting: SortMode, +) -> std::vec::IntoIter<(TreeIndex, &EntryData)> { + use SortMode::*; + tree.neighbors_directed(node_idx, Direction::Outgoing) + .filter_map(|idx| tree.node_weight(idx).map(|w| (idx, w))) + .sorted_by(|(_, l), (_, r)| match sorting { + SizeDescending => r.size.cmp(&l.size), + SizeAscending => l.size.cmp(&r.size), + }) +} + /// Specifies a way to format bytes #[derive(Clone, Copy)] pub enum ByteFormat { diff --git a/src/interactive/app.rs b/src/interactive/app.rs index 622fa71..998d337 100644 --- a/src/interactive/app.rs +++ b/src/interactive/app.rs @@ -1,5 +1,5 @@ use super::widgets::{DisplayState, MainWindow}; -use crate::{interactive::Traversal, ByteFormat, WalkOptions, WalkResult}; +use crate::{interactive::Traversal, sorted_entries, ByteFormat, WalkOptions, WalkResult}; use failure::Error; use std::{io, path::PathBuf}; use termion::input::{Keys, TermReadEventsAndRaw}; @@ -99,11 +99,17 @@ impl TerminalApp { })?; Ok(()) })?; + + let sorting = Default::default(); + let root = traversal.root_index; + let selected = sorted_entries(&traversal.tree, root, sorting) + .next() + .map(|(idx, _)| idx); Ok(TerminalApp { state: DisplayState { - root: traversal.root_index, - selected: None, - sorting: Default::default(), + root, + selected, + sorting, }, display: display_options, traversal: traversal, diff --git a/src/interactive/widgets.rs b/src/interactive/widgets.rs index 86caef5..3cb92bd 100644 --- a/src/interactive/widgets.rs +++ b/src/interactive/widgets.rs @@ -1,6 +1,5 @@ use super::{DisplayOptions, Traversal, Tree, TreeIndex}; -use crate::ByteFormat; -use itertools::Itertools; +use crate::{sorted_entries, ByteFormat}; use tui::layout::{Constraint, Direction, Layout}; use tui::style::{Color, Style}; use tui::{ @@ -126,27 +125,16 @@ impl<'a> Widget for Entries<'a> { display, sorting, } = self; - use petgraph::Direction; - use SortMode::*; - List::new( - tree.neighbors_directed(*root, Direction::Outgoing) - .filter_map(|w| tree.node_weight(w)) - .sorted_by(|l, r| match sorting { - SizeDescending => l.size.cmp(&r.size), - SizeAscending => r.size.cmp(&l.size), - }) - .rev() - .map(|w| { - Text::Raw( - format!( - "{} | ----- | {}", - display.byte_format.display(w.size), - w.name.to_string_lossy() - ) - .into(), - ) - }), - ) + List::new(sorted_entries(tree, *root, *sorting).map(|(_, w)| { + Text::Raw( + format!( + "{} | ----- | {}", + display.byte_format.display(w.size), + w.name.to_string_lossy() + ) + .into(), + ) + })) .block(Block::default().borders(Borders::ALL).title("Entries")) .start_corner(Corner::TopLeft) .draw(area, buf); diff --git a/tests/interactive.rs b/tests/interactive.rs index e6a1efe..9a923d9 100644 --- a/tests/interactive.rs +++ b/tests/interactive.rs @@ -1,5 +1,4 @@ mod app { - use dua::interactive::TreeIndex; use dua::{ interactive::{widgets::SortMode, EntryData, TerminalApp, Tree, TreeIndexType}, ByteFormat, Color, TraversalSorting, WalkOptions, @@ -44,32 +43,44 @@ mod app { Ok(()) } + fn node_by(app: &TerminalApp, id: TreeIndexType) -> &EntryData { + app.traversal.tree.node_weight(id.into()).unwrap() + } + #[test] fn simple_user_journey() -> Result<(), Error> { let long_root = "sample-02/dir"; let (mut terminal, mut app) = initialized_app_and_terminal(&["sample-02", long_root])?; + + // after initialization, we expect that... assert_eq!( app.state.sorting, SortMode::SizeDescending, - "it starts in descending order by size" + "it will sort entries in descending order by size" ); assert_eq!( - app.traversal - .tree - .node_weight(TreeIndex::new(11)) - .unwrap() - .name, + node_by(&app, 11).name, OsString::from(format!("{}/{}", FIXTURE_PATH, long_root)), "the roots are always listed with the given (possibly long) names", ); + assert_eq!( + node_by(&app, 1).name, + node_by( + &app, + app.state.selected.as_ref().unwrap().index() as TreeIndexType + ) + .name, + "it selects the first node in the list", + ); + // when hitting the S key app.process_events(&mut terminal, b"s".keys())?; assert_eq!( app.state.sorting, SortMode::SizeAscending, - "it sets the sort to size ascending" + "it sets the sort mode to ascending by size" ); Ok(()) |