summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPiotr Wach <pwach@bloomberg.net>2024-01-07 09:12:46 +0000
committerPiotr Wach <pwach@bloomberg.net>2024-01-07 09:12:46 +0000
commit5123cf584ab68c0a2f491580289c7243e8651bfa (patch)
tree6b983c21a48873ca8e6a246b80f2efbc7c0df51b /src
parentcf3c507bb43221066acf96cde778b66bbd578669 (diff)
Move TerminalApp to separate file
Diffstat (limited to 'src')
-rw-r--r--src/interactive/app/eventloop.rs162
-rw-r--r--src/interactive/app/mod.rs1
-rw-r--r--src/interactive/app/terminal_app.rs173
-rw-r--r--src/interactive/app/tests/utils.rs2
-rw-r--r--src/main.rs2
5 files changed, 177 insertions, 163 deletions
diff --git a/src/interactive/app/eventloop.rs b/src/interactive/app/eventloop.rs
index 8132f6b..2d2459c 100644
--- a/src/interactive/app/eventloop.rs
+++ b/src/interactive/app/eventloop.rs
@@ -337,166 +337,6 @@ where
Ok(())
}
-/// State and methods representing the interactive disk usage analyser for the terminal
-pub struct TerminalApp {
- pub traversal: Traversal,
- pub display: DisplayOptions,
- pub state: AppState,
- pub window: MainWindow,
-}
-
-type KeyboardInputAndApp = (crossbeam::channel::Receiver<Event>, TerminalApp);
-
-impl TerminalApp {
- pub fn refresh_view<B>(&mut self, terminal: &mut Terminal<B>)
- where
- B: Backend,
- {
- // Use an event that does nothing to trigger a refresh
- self.state
- .process_events(
- &mut self.window,
- &mut self.traversal,
- &mut self.display,
- terminal,
- std::iter::once(Event::Key(refresh_key())),
- )
- .ok();
- }
-
- pub fn process_events<B>(
- &mut self,
- terminal: &mut Terminal<B>,
- events: impl Iterator<Item = Event>,
- ) -> Result<WalkResult>
- where
- B: Backend,
- {
- match self.state.process_events(
- &mut self.window,
- &mut self.traversal,
- &mut self.display,
- terminal,
- events,
- )? {
- ProcessingResult::Finished(res) | ProcessingResult::ExitRequested(res) => Ok(res),
- }
- }
-
- pub fn initialize<B>(
- terminal: &mut Terminal<B>,
- options: WalkOptions,
- input_paths: Vec<PathBuf>,
- keys_rx: Receiver<Event>,
- ) -> Result<Option<KeyboardInputAndApp>>
- where
- B: Backend,
- {
- terminal.hide_cursor()?;
- terminal.clear()?;
-
- let mut display: DisplayOptions = options.clone().into();
- display.byte_vis = ByteVisualization::PercentageAndBar;
-
- let mut window = MainWindow::default();
-
- // #[inline]
- // fn fetch_buffered_key_events(keys_rx: &Receiver<Event>) -> Vec<Event> {
- // let mut keys = Vec::new();
- // while let Ok(key) = keys_rx.try_recv() {
- // keys.push(key);
- // }
- // keys
- // }
-
- let mut state = AppState {
- is_scanning: false,
- ..Default::default()
- };
-
- // let mut received_events = false;
- // let traversal =
- // Traversal::from_walk(options, input_paths, &keys_rx, |traversal, event| {
- // if !received_events {
- // state.navigation_mut().view_root = traversal.root_index;
- // }
- // state.entries = sorted_entries(
- // &traversal.tree,
- // state.navigation().view_root,
- // state.sorting,
- // state.glob_root(),
- // );
- // if !received_events {
- // state.navigation_mut().selected = state.entries.first().map(|b| b.index);
- // }
- // state.reset_message(); // force "scanning" to appear
-
- // let mut events = fetch_buffered_key_events(&keys_rx);
- // if let Some(event) = event {
- // // This update is triggered by a user event, insert it
- // // before any events fetched later.
- // events.insert(0, event);
- // }
- // received_events |= !events.is_empty();
-
- // let should_exit = match state.process_events(
- // &mut window,
- // traversal,
- // &mut display,
- // terminal,
- // events.into_iter(),
- // )? {
- // ProcessingResult::ExitRequested(_) => true,
- // ProcessingResult::Finished(_) => false,
- // };
-
- // Ok(should_exit)
- // })?;
-
- // let traversal = match traversal {
- // Some(t) => t,
- // None => return Ok(None),
- // };
-
- // state.is_scanning = false;
- // if !received_events {
- // }
-
- let traversal = {
- let mut tree = Tree::new();
- let root_index = tree.add_node(EntryData::default());
- Traversal {
- tree,
- root_index,
- entries_traversed: 0,
- start: std::time::Instant::now(),
- elapsed: None,
- io_errors: 0,
- total_bytes: None,
- }
- };
-
- state.navigation_mut().view_root = traversal.root_index;
- state.entries = sorted_entries(
- &traversal.tree,
- state.navigation().view_root,
- state.sorting,
- state.glob_root(),
- );
- state.navigation_mut().selected = state.entries.first().map(|b| b.index);
-
- let mut app = TerminalApp {
- state,
- display,
- traversal,
- window,
- };
- app.refresh_view(terminal);
-
- Ok(Some((keys_rx, app)))
- }
-}
-
-fn refresh_key() -> KeyEvent {
+pub fn refresh_key() -> KeyEvent {
KeyEvent::new(KeyCode::Char('\r'), KeyModifiers::ALT)
}
diff --git a/src/interactive/app/mod.rs b/src/interactive/app/mod.rs
index 8d27e46..73eb2f2 100644
--- a/src/interactive/app/mod.rs
+++ b/src/interactive/app/mod.rs
@@ -5,6 +5,7 @@ mod handlers;
pub mod input;
mod navigation;
pub mod tree_view;
+pub mod terminal_app;
pub use bytevis::*;
pub use common::*;
diff --git a/src/interactive/app/terminal_app.rs b/src/interactive/app/terminal_app.rs
new file mode 100644
index 0000000..b19bf1b
--- /dev/null
+++ b/src/interactive/app/terminal_app.rs
@@ -0,0 +1,173 @@
+use std::path::PathBuf;
+
+use crossbeam::channel::Receiver;
+use crosstermion::input::Event;
+use dua::{traverse::{Traversal, Tree, EntryData}, WalkResult, WalkOptions};
+use tui::prelude::Backend;
+use tui_react::Terminal;
+use anyhow::Result;
+
+use crate::interactive::widgets::MainWindow;
+
+use super::{DisplayOptions, AppState, ProcessingResult, ByteVisualization, sorted_entries, refresh_key};
+
+
+/// State and methods representing the interactive disk usage analyser for the terminal
+pub struct TerminalApp {
+ pub traversal: Traversal,
+ pub display: DisplayOptions,
+ pub state: AppState,
+ pub window: MainWindow,
+}
+
+type KeyboardInputAndApp = (crossbeam::channel::Receiver<Event>, TerminalApp);
+
+impl TerminalApp {
+ pub fn refresh_view<B>(&mut self, terminal: &mut Terminal<B>)
+ where
+ B: Backend,
+ {
+ // Use an event that does nothing to trigger a refresh
+ self.state
+ .process_events(
+ &mut self.window,
+ &mut self.traversal,
+ &mut self.display,
+ terminal,
+ std::iter::once(Event::Key(refresh_key())),
+ )
+ .ok();
+ }
+
+ pub fn process_events<B>(
+ &mut self,
+ terminal: &mut Terminal<B>,
+ events: impl Iterator<Item = Event>,
+ ) -> Result<WalkResult>
+ where
+ B: Backend,
+ {
+ match self.state.process_events(
+ &mut self.window,
+ &mut self.traversal,
+ &mut self.display,
+ terminal,
+ events,
+ )? {
+ ProcessingResult::Finished(res) | ProcessingResult::ExitRequested(res) => Ok(res),
+ }
+ }
+
+ pub fn initialize<B>(
+ terminal: &mut Terminal<B>,
+ options: WalkOptions,
+ input_paths: Vec<PathBuf>,
+ keys_rx: Receiver<Event>,
+ ) -> Result<Option<KeyboardInputAndApp>>
+ where
+ B: Backend,
+ {
+ terminal.hide_cursor()?;
+ terminal.clear()?;
+
+ let mut display: DisplayOptions = options.clone().into();
+ display.byte_vis = ByteVisualization::PercentageAndBar;
+
+ let mut window = MainWindow::default();
+
+ // #[inline]
+ // fn fetch_buffered_key_events(keys_rx: &Receiver<Event>) -> Vec<Event> {
+ // let mut keys = Vec::new();
+ // while let Ok(key) = keys_rx.try_recv() {
+ // keys.push(key);
+ // }
+ // keys
+ // }
+
+ let mut state = AppState {
+ is_scanning: false,
+ ..Default::default()
+ };
+
+ // let mut received_events = false;
+ // let traversal =
+ // Traversal::from_walk(options, input_paths, &keys_rx, |traversal, event| {
+ // if !received_events {
+ // state.navigation_mut().view_root = traversal.root_index;
+ // }
+ // state.entries = sorted_entries(
+ // &traversal.tree,
+ // state.navigation().view_root,
+ // state.sorting,
+ // state.glob_root(),
+ // );
+ // if !received_events {
+ // state.navigation_mut().selected = state.entries.first().map(|b| b.index);
+ // }
+ // state.reset_message(); // force "scanning" to appear
+
+ // let mut events = fetch_buffered_key_events(&keys_rx);
+ // if let Some(event) = event {
+ // // This update is triggered by a user event, insert it
+ // // before any events fetched later.
+ // events.insert(0, event);
+ // }
+ // received_events |= !events.is_empty();
+
+ // let should_exit = match state.process_events(
+ // &mut window,
+ // traversal,
+ // &mut display,
+ // terminal,
+ // events.into_iter(),
+ // )? {
+ // ProcessingResult::ExitRequested(_) => true,
+ // ProcessingResult::Finished(_) => false,
+ // };
+
+ // Ok(should_exit)
+ // })?;
+
+ // let traversal = match traversal {
+ // Some(t) => t,
+ // None => return Ok(None),
+ // };
+
+ // state.is_scanning = false;
+ // if !received_events {
+ // }
+
+ let traversal = {
+ let mut tree = Tree::new();
+ let root_index = tree.add_node(EntryData::default());
+ Traversal {
+ tree,
+ root_index,
+ entries_traversed: 0,
+ start: std::time::Instant::now(),
+ elapsed: None,
+ io_errors: 0,
+ total_bytes: None,
+ }
+ };
+
+ state.navigation_mut().view_root = traversal.root_index;
+ state.entries = sorted_entries(
+ &traversal.tree,
+ state.navigation().view_root,
+ state.sorting,
+ state.glob_root(),
+ );
+ state.navigation_mut().selected = state.entries.first().map(|b| b.index);
+
+ let mut app = TerminalApp {
+ state,
+ display,
+ traversal,
+ window,
+ };
+ app.refresh_view(terminal);
+
+ Ok(Some((keys_rx, app)))
+ }
+}
diff --git a/src/interactive/app/tests/utils.rs b/src/interactive/app/tests/utils.rs
index f865750..82cf00b 100644
--- a/src/interactive/app/tests/utils.rs
+++ b/src/interactive/app/tests/utils.rs
@@ -18,7 +18,7 @@ use std::{
use tui::backend::TestBackend;
use tui_react::Terminal;
-use crate::interactive::{app::tests::FIXTURE_PATH, TerminalApp};
+use crate::interactive::{app::tests::FIXTURE_PATH, terminal_app::TerminalApp};
pub fn into_keys<'a>(
codes: impl IntoIterator<Item = KeyCode> + 'a,
diff --git a/src/main.rs b/src/main.rs
index 6b9ffa3..636b01a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,6 +8,7 @@ use std::fs::OpenOptions;
use std::{fs, io, io::Write, path::PathBuf, process};
use crate::interactive::input::input_channel;
+use crate::interactive::terminal_app::TerminalApp;
mod crossdev;
#[cfg(feature = "tui-crossplatform")]
@@ -53,7 +54,6 @@ fn main() -> Result<()> {
let res = match opt.command {
#[cfg(feature = "tui-crossplatform")]
Some(Interactive { input }) => {
- use crate::interactive::{TerminalApp};
use anyhow::{anyhow, Context};
use crosstermion::terminal::{tui::new_terminal, AlternateRawScreen};