summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/interactive/app.rs11
-rw-r--r--src/interactive/mod.rs2
-rw-r--r--src/interactive/widgets.rs34
-rw-r--r--tests/interactive.rs27
4 files changed, 66 insertions, 8 deletions
diff --git a/src/interactive/app.rs b/src/interactive/app.rs
index 95606c1..622fa71 100644
--- a/src/interactive/app.rs
+++ b/src/interactive/app.rs
@@ -26,7 +26,7 @@ pub struct TerminalApp {
}
impl TerminalApp {
- fn draw_to_terminal<B>(&self, terminal: &mut Terminal<B>) -> Result<(), Error>
+ fn draw<B>(&self, terminal: &mut Terminal<B>) -> Result<(), Error>
where
B: Backend,
{
@@ -35,6 +35,7 @@ impl TerminalApp {
display,
state,
} = self;
+
terminal.draw(|mut f| {
let full_screen = f.size();
MainWindow {
@@ -44,6 +45,7 @@ impl TerminalApp {
}
.render(&mut f, full_screen)
})?;
+
Ok(())
}
pub fn process_events<B, R>(
@@ -57,13 +59,14 @@ impl TerminalApp {
{
use termion::event::Key::{Char, Ctrl};
- self.draw_to_terminal(terminal)?;
+ self.draw(terminal)?;
for key in keys.filter_map(Result::ok) {
match key {
+ Char('s') => self.state.sorting.toggle_size(),
Ctrl('c') | Char('\n') | Char('q') => break,
_ => {}
};
- self.draw_to_terminal(terminal)?;
+ self.draw(terminal)?;
}
Ok(WalkResult {
num_errors: self.traversal.io_errors,
@@ -85,6 +88,7 @@ impl TerminalApp {
let state = DisplayState {
root: traversal.root_index,
selected: None,
+ sorting: Default::default(),
};
MainWindow {
traversal,
@@ -99,6 +103,7 @@ impl TerminalApp {
state: DisplayState {
root: traversal.root_index,
selected: None,
+ sorting: Default::default(),
},
display: display_options,
traversal: traversal,
diff --git a/src/interactive/mod.rs b/src/interactive/mod.rs
index 84130f8..040fd10 100644
--- a/src/interactive/mod.rs
+++ b/src/interactive/mod.rs
@@ -1,6 +1,6 @@
mod app;
mod traverse;
-mod widgets;
+pub mod widgets;
pub use self::app::*;
pub use self::traverse::*;
diff --git a/src/interactive/widgets.rs b/src/interactive/widgets.rs
index 6b7cd80..86caef5 100644
--- a/src/interactive/widgets.rs
+++ b/src/interactive/widgets.rs
@@ -13,11 +13,35 @@ pub struct Entries<'a> {
pub tree: &'a Tree,
pub root: TreeIndex,
pub display: DisplayOptions,
+ pub sorting: SortMode,
+}
+
+#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq)]
+pub enum SortMode {
+ SizeDescending,
+ SizeAscending,
+}
+
+impl SortMode {
+ pub fn toggle_size(&mut self) {
+ use SortMode::*;
+ *self = match self {
+ SizeAscending => SizeDescending,
+ SizeDescending => SizeAscending,
+ }
+ }
+}
+
+impl Default for SortMode {
+ fn default() -> Self {
+ SortMode::SizeDescending
+ }
}
pub struct DisplayState {
pub root: TreeIndex,
pub selected: Option<TreeIndex>,
+ pub sorting: SortMode,
}
pub struct MainWindow<'a, 'b> {
@@ -81,6 +105,7 @@ impl<'a, 'b> Widget for MainWindow<'a, 'b> {
tree: &tree,
root: state.root,
display: *display,
+ sorting: state.sorting,
}
.draw(entries, buf);
@@ -95,16 +120,21 @@ impl<'a, 'b> Widget for MainWindow<'a, 'b> {
impl<'a> Widget for Entries<'a> {
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
- use petgraph::Direction;
let Self {
tree,
root,
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| l.size.cmp(&r.size))
+ .sorted_by(|l, r| match sorting {
+ SizeDescending => l.size.cmp(&r.size),
+ SizeAscending => r.size.cmp(&l.size),
+ })
.rev()
.map(|w| {
Text::Raw(
diff --git a/tests/interactive.rs b/tests/interactive.rs
index 159f05e..1fb32da 100644
--- a/tests/interactive.rs
+++ b/tests/interactive.rs
@@ -1,10 +1,13 @@
mod app {
- use dua::interactive::{EntryData, TerminalApp, Tree, TreeIndexType};
- use dua::{ByteFormat, Color, TraversalSorting, WalkOptions};
+ use dua::{
+ interactive::{widgets::SortMode, EntryData, TerminalApp, Tree, TreeIndexType},
+ ByteFormat, Color, TraversalSorting, WalkOptions,
+ };
use failure::Error;
use petgraph::prelude::NodeIndex;
use pretty_assertions::assert_eq;
use std::{ffi::OsString, fmt, path::Path};
+ use termion::input::TermRead;
use tui::backend::TestBackend;
use tui::Terminal;
@@ -38,6 +41,26 @@ mod app {
Ok(())
}
+ #[test]
+ fn simple_user_journey() -> Result<(), Error> {
+ let (mut terminal, mut app) = initialized_app_and_terminal("sample-02")?;
+ assert_eq!(
+ app.state.sorting,
+ SortMode::SizeDescending,
+ "it starts in descending order by size"
+ );
+
+ // 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"
+ );
+
+ Ok(())
+ }
+
fn initialized_app_and_terminal(
fixture_path: &str,
) -> Result<(Terminal<TestBackend>, TerminalApp), Error> {