swarm repositories / source
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/memview/src/linux.rs151
-rw-r--r--crates/memview/src/main.rs175
-rw-r--r--crates/memview/src/unsupported.rs4
3 files changed, 162 insertions, 168 deletions
diff --git a/crates/memview/src/linux.rs b/crates/memview/src/linux.rs
new file mode 100644
index 0000000..1454329
--- /dev/null
+++ b/crates/memview/src/linux.rs
@@ -0,0 +1,151 @@
+use crate::app::{App, WorkerCommand, spawn_worker};
+use crate::ui;
+use clap::Parser;
+use color_eyre::eyre::Result;
+use crossterm::cursor::{Hide, Show};
+use crossterm::event::{
+ self, DisableFocusChange, DisableMouseCapture, EnableFocusChange, EnableMouseCapture, Event,
+ KeyEventKind,
+};
+use crossterm::execute;
+use crossterm::terminal::{
+ EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode,
+};
+use ratatui::Terminal;
+use ratatui::backend::CrosstermBackend;
+use std::io::{self, Stdout};
+use std::time::{Duration, Instant};
+
+const FOCUSED_IDLE_POLL: Duration = Duration::from_millis(500);
+const BACKGROUND_IDLE_POLL: Duration = Duration::from_secs(1);
+const ANIMATED_REDRAW: Duration = Duration::from_millis(250);
+
+#[derive(Debug, Parser)]
+#[command(author, version, about = "ncdu-like RAM accounting for Linux /proc")]
+struct Cli {
+ #[arg(long, default_value_t = 5000)]
+ refresh_ms: u64,
+}
+
+pub fn run() -> Result<()> {
+ color_eyre::install()?;
+ let cli = Cli::parse();
+ let (commands, events) = spawn_worker(Duration::from_millis(cli.refresh_ms));
+ let mut terminal = TerminalGuard::enter()?;
+ let mut app = App::new();
+ app.set_terminal_height(terminal.height()?);
+ app.start_visible_work(&commands);
+ let mut dirty = true;
+ let mut next_animated_redraw = Instant::now();
+
+ loop {
+ while let Ok(event) = events.try_recv() {
+ app.apply_worker_event(event, &commands);
+ dirty = true;
+ }
+ if app.poll_deletion(&commands) {
+ dirty = true;
+ }
+
+ let now = Instant::now();
+ let redraw_animation = app.needs_periodic_redraw() && now >= next_animated_redraw;
+ if app.is_focused() && (dirty || redraw_animation) {
+ terminal.draw(|frame| ui::render(frame, &app))?;
+ dirty = false;
+ next_animated_redraw = Instant::now() + ANIMATED_REDRAW;
+ }
+
+ if event::poll(poll_timeout(&app, next_animated_redraw))? {
+ match event::read()? {
+ Event::Key(key) => {
+ if key.kind != KeyEventKind::Press {
+ continue;
+ }
+ if app.handle_key(key, &commands) {
+ break;
+ }
+ dirty = true;
+ }
+ Event::Mouse(mouse) => {
+ if app.handle_mouse(mouse, &commands) {
+ dirty = true;
+ }
+ }
+ Event::Resize(_, height) => {
+ app.set_terminal_height(height);
+ dirty = true;
+ }
+ Event::FocusGained => {
+ app.set_focused(true, &commands);
+ dirty = true;
+ }
+ Event::FocusLost => {
+ app.set_focused(false, &commands);
+ dirty = false;
+ }
+ Event::Paste(_) => {}
+ }
+ }
+ }
+
+ let _ = commands.send(WorkerCommand::Shutdown);
+ Ok(())
+}
+
+fn poll_timeout(app: &App, next_animated_redraw: Instant) -> Duration {
+ if !app.is_focused() {
+ return BACKGROUND_IDLE_POLL;
+ }
+ if app.needs_periodic_redraw() {
+ FOCUSED_IDLE_POLL.min(next_animated_redraw.saturating_duration_since(Instant::now()))
+ } else {
+ FOCUSED_IDLE_POLL
+ }
+}
+
+struct TerminalGuard {
+ terminal: Terminal<CrosstermBackend<Stdout>>,
+}
+
+impl TerminalGuard {
+ fn enter() -> Result<Self> {
+ enable_raw_mode()?;
+ let mut stdout = io::stdout();
+ execute!(
+ stdout,
+ EnterAlternateScreen,
+ EnableMouseCapture,
+ EnableFocusChange,
+ Hide
+ )?;
+ let backend = CrosstermBackend::new(stdout);
+ let terminal = Terminal::new(backend)?;
+ Ok(Self { terminal })
+ }
+
+ fn draw<F>(&mut self, draw: F) -> Result<()>
+ where
+ F: FnOnce(&mut ratatui::Frame<'_>),
+ {
+ let _ = self.terminal.draw(draw)?;
+ Ok(())
+ }
+
+ fn height(&self) -> Result<u16> {
+ Ok(self.terminal.size()?.height)
+ }
+}
+
+impl Drop for TerminalGuard {
+ fn drop(&mut self) {
+ let _ = disable_raw_mode();
+ let _ = execute!(
+ self.terminal.backend_mut(),
+ Show,
+ DisableFocusChange,
+ DisableMouseCapture,
+ LeaveAlternateScreen
+ );
+ let _ = self.terminal.show_cursor();
+ }
+}
diff --git a/crates/memview/src/main.rs b/crates/memview/src/main.rs
index b68624f..64665b7 100644
--- a/crates/memview/src/main.rs
+++ b/crates/memview/src/main.rs
@@ -1,6 +1,8 @@
#[cfg(target_os = "linux")]
mod app;
#[cfg(target_os = "linux")]
+mod linux;
+#[cfg(target_os = "linux")]
mod model;
#[cfg(target_os = "linux")]
mod nav;
@@ -11,178 +13,15 @@ mod search;
#[cfg(target_os = "linux")]
mod ui;
-#[cfg(target_os = "linux")]
-use crate::app::{App, WorkerCommand, spawn_worker};
-#[cfg(target_os = "linux")]
-use clap::Parser;
-#[cfg(target_os = "linux")]
-use color_eyre::eyre::Result;
-#[cfg(target_os = "linux")]
-use crossterm::cursor::{Hide, Show};
-#[cfg(target_os = "linux")]
-use crossterm::event::{
- self, DisableFocusChange, DisableMouseCapture, EnableFocusChange, EnableMouseCapture, Event,
- KeyEventKind,
-};
-#[cfg(target_os = "linux")]
-use crossterm::execute;
-#[cfg(target_os = "linux")]
-use crossterm::terminal::{
- EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode,
-};
-#[cfg(target_os = "linux")]
-use ratatui::Terminal;
-#[cfg(target_os = "linux")]
-use ratatui::backend::CrosstermBackend;
-#[cfg(target_os = "linux")]
-use std::io::{self, Stdout};
-#[cfg(target_os = "linux")]
-use std::time::{Duration, Instant};
-
-#[cfg(target_os = "linux")]
-const FOCUSED_IDLE_POLL: Duration = Duration::from_millis(500);
-#[cfg(target_os = "linux")]
-const BACKGROUND_IDLE_POLL: Duration = Duration::from_secs(1);
-#[cfg(target_os = "linux")]
-const ANIMATED_REDRAW: Duration = Duration::from_millis(250);
-
-#[cfg(target_os = "linux")]
-#[derive(Debug, Parser)]
-#[command(author, version, about = "ncdu-like RAM accounting for Linux /proc")]
-struct Cli {
- #[arg(long, default_value_t = 5000)]
- refresh_ms: u64,
-}
+#[cfg(not(target_os = "linux"))]
+mod unsupported;
#[cfg(target_os = "linux")]
-fn main() -> Result<()> {
- color_eyre::install()?;
- let cli = Cli::parse();
- let (commands, events) = spawn_worker(Duration::from_millis(cli.refresh_ms));
- let mut terminal = TerminalGuard::enter()?;
- let mut app = App::new();
- app.set_terminal_height(terminal.height()?);
- app.start_visible_work(&commands);
- let mut dirty = true;
- let mut next_animated_redraw = Instant::now();
-
- loop {
- while let Ok(event) = events.try_recv() {
- app.apply_worker_event(event, &commands);
- dirty = true;
- }
- if app.poll_deletion(&commands) {
- dirty = true;
- }
-
- let now = Instant::now();
- let redraw_animation = app.needs_periodic_redraw() && now >= next_animated_redraw;
- if app.is_focused() && (dirty || redraw_animation) {
- terminal.draw(|frame| ui::render(frame, &app))?;
- dirty = false;
- next_animated_redraw = Instant::now() + ANIMATED_REDRAW;
- }
-
- if event::poll(poll_timeout(&app, next_animated_redraw))? {
- match event::read()? {
- Event::Key(key) => {
- if key.kind != KeyEventKind::Press {
- continue;
- }
- if app.handle_key(key, &commands) {
- break;
- }
- dirty = true;
- }
- Event::Mouse(mouse) => {
- if app.handle_mouse(mouse, &commands) {
- dirty = true;
- }
- }
- Event::Resize(_, height) => {
- app.set_terminal_height(height);
- dirty = true;
- }
- Event::FocusGained => {
- app.set_focused(true, &commands);
- dirty = true;
- }
- Event::FocusLost => {
- app.set_focused(false, &commands);
- dirty = false;
- }
- Event::Paste(_) => {}
- }
- }
- }
-
- let _ = commands.send(WorkerCommand::Shutdown);
- Ok(())
+fn main() -> color_eyre::eyre::Result<()> {
+ linux::run()
}
#[cfg(not(target_os = "linux"))]
fn main() {
- eprintln!("memview is not supported on this system: Linux is required.");
- std::process::exit(1);
-}
-
-#[cfg(target_os = "linux")]
-fn poll_timeout(app: &App, next_animated_redraw: Instant) -> Duration {
- if !app.is_focused() {
- return BACKGROUND_IDLE_POLL;
- }
- if app.needs_periodic_redraw() {
- FOCUSED_IDLE_POLL.min(next_animated_redraw.saturating_duration_since(Instant::now()))
- } else {
- FOCUSED_IDLE_POLL
- }
-}
-
-#[cfg(target_os = "linux")]
-struct TerminalGuard {
- terminal: Terminal<CrosstermBackend<Stdout>>,
-}
-
-#[cfg(target_os = "linux")]
-impl TerminalGuard {
- fn enter() -> Result<Self> {
- enable_raw_mode()?;
- let mut stdout = io::stdout();
- execute!(
- stdout,
- EnterAlternateScreen,
- EnableMouseCapture,
- EnableFocusChange,
- Hide
- )?;
- let backend = CrosstermBackend::new(stdout);
- let terminal = Terminal::new(backend)?;
- Ok(Self { terminal })
- }
-
- fn draw<F>(&mut self, draw: F) -> Result<()>
- where
- F: FnOnce(&mut ratatui::Frame<'_>),
- {
- let _ = self.terminal.draw(draw)?;
- Ok(())
- }
-
- fn height(&self) -> Result<u16> {
- Ok(self.terminal.size()?.height)
- }
-}
-
-impl Drop for TerminalGuard {
- fn drop(&mut self) {
- let _ = disable_raw_mode();
- let _ = execute!(
- self.terminal.backend_mut(),
- Show,
- DisableFocusChange,
- DisableMouseCapture,
- LeaveAlternateScreen
- );
- let _ = self.terminal.show_cursor();
- }
+ unsupported::run();
}
diff --git a/crates/memview/src/unsupported.rs b/crates/memview/src/unsupported.rs
new file mode 100644
index 0000000..9be3132
--- /dev/null
+++ b/crates/memview/src/unsupported.rs
@@ -0,0 +1,4 @@
+pub fn run() -> ! {
+ eprintln!("memview is not supported on this system: Linux is required.");
+ std::process::exit(1);
+}