summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common.rs21
-rw-r--r--src/interactive/app.rs14
-rw-r--r--src/interactive/widgets.rs34
-rw-r--r--tests/interactive.rs27
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(())