diff options
author | Santo Cariotti <santo@dcariotti.me> | 2023-10-15 21:08:27 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2023-10-15 21:08:27 +0200 |
commit | 073d565b303bde5d3a79f5d5c426d6c2822912d4 (patch) | |
tree | 849dd1149923543f42625cdedf04dbb0f85279c5 | |
parent | 1492ea73797a415070709591eb0738296231476c (diff) |
Move UI in a module
-rw-r--r-- | src/main.rs | 97 | ||||
-rw-r--r-- | src/ui.rs | 99 |
2 files changed, 103 insertions, 93 deletions
diff --git a/src/main.rs b/src/main.rs index b9a8821..8e99cb5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,12 @@ mod trace; -use crossterm::{ - event::{self, Event, KeyCode}, - terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, - ExecutableCommand, -}; -use ratatui::{prelude::*, widgets::*}; +mod ui; use std::{ - io::{self, stdout, Write}, + io::{self, Write}, str, }; use crate::trace::{exec, trace}; +use crate::ui::run_tui; use clap::Parser; use fork::{fork, Fork}; use nix::unistd::Pid; @@ -30,22 +26,6 @@ struct Args { no_tui: bool, } -struct UI { - height: usize, - max_lines: usize, - scroll: usize, -} - -impl UI { - fn new() -> UI { - UI { - height: 0, - max_lines: 0, - scroll: 0, - } - } -} - /// Create a fork of the program and execute the process in the child. Parent gets the pid /// value and trace it. fn main() -> anyhow::Result<()> { @@ -60,79 +40,10 @@ fn main() -> anyhow::Result<()> { let lines = str::from_utf8(&output)?.trim(); if !args.no_tui { - enable_raw_mode()?; - stdout().execute(EnterAlternateScreen)?; - let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; - - let mut ui = UI::new(); - ui.max_lines = lines.split('\n').count() + 1; - - let mut should_quit = false; - while !should_quit { - ui.height = terminal.get_frame().size().height as usize; - terminal.draw(move |frame| { - let size = frame.size(); - frame.render_widget( - Paragraph::new(lines) - .block( - Block::default() - .border_style(Style::default().fg(Color::Yellow)) - .title(format!("[{pid}]")) - .title( - block::Title::from(format!( - "[lines {}-{}]", - ui.scroll, - ui.scroll + ui.height - )) - .position(block::Position::Bottom) - .alignment(Alignment::Right), - ) - .borders(Borders::ALL), - ) - .scroll((ui.scroll as u16, 0)), - size, - ); - })?; - should_quit = handle_events(&mut ui)?; - } - - disable_raw_mode()?; - stdout().execute(LeaveAlternateScreen)?; + let _ = run_tui(pid, lines)?; } else { writeln!(io::stdout(), "{lines}")?; } Ok(()) } - -fn handle_events(ui: &mut UI) -> io::Result<bool> { - if event::poll(std::time::Duration::from_millis(50))? { - if let Event::Key(key) = event::read()? { - if key.kind == event::KeyEventKind::Press { - match key.code { - KeyCode::Char('q') => { - return Ok(true); - } - KeyCode::Char('j') | KeyCode::Down => { - if ui.scroll < (ui.max_lines - ui.height + 1) { - ui.scroll += 1; - } - } - KeyCode::Char('J') | KeyCode::Char('G') => { - ui.scroll = ui.max_lines - ui.height + 1; - } - KeyCode::Char('k') | KeyCode::Up => { - if ui.scroll > 1 { - ui.scroll -= 1; - } - } - KeyCode::Char('K') | KeyCode::Char('0') => { - ui.scroll = ui.height; - } - _ => {} - } - } - } - } - Ok(false) -} diff --git a/src/ui.rs b/src/ui.rs new file mode 100644 index 0000000..4d197bc --- /dev/null +++ b/src/ui.rs @@ -0,0 +1,99 @@ +use crossterm::{ + event::{self, Event, KeyCode}, + terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, + ExecutableCommand, +}; +use nix::unistd::Pid; +use ratatui::{prelude::*, widgets::*}; +use std::io::{self, stdout}; + +struct UI { + height: usize, + max_lines: usize, + scroll: usize, +} + +impl UI { + fn new() -> UI { + UI { + height: 0, + max_lines: 0, + scroll: 0, + } + } +} + +fn handle_events(ui: &mut UI) -> io::Result<bool> { + if event::poll(std::time::Duration::from_millis(50))? { + if let Event::Key(key) = event::read()? { + if key.kind == event::KeyEventKind::Press { + match key.code { + KeyCode::Char('q') => { + return Ok(true); + } + KeyCode::Char('j') | KeyCode::Down => { + if ui.scroll < (ui.max_lines - ui.height + 1) { + ui.scroll += 1; + } + } + KeyCode::Char('J') | KeyCode::Char('G') => { + ui.scroll = ui.max_lines - ui.height + 1; + } + KeyCode::Char('k') | KeyCode::Up => { + if ui.scroll > 1 { + ui.scroll -= 1; + } + } + KeyCode::Char('K') | KeyCode::Char('0') => { + ui.scroll = ui.height; + } + _ => {} + } + } + } + } + Ok(false) +} + +pub fn run_tui(pid: Pid, lines: &str) -> anyhow::Result<()> { + enable_raw_mode()?; + stdout().execute(EnterAlternateScreen)?; + let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; + + let mut ui = UI::new(); + ui.max_lines = lines.split('\n').count() + 1; + + let mut should_quit = false; + while !should_quit { + ui.height = terminal.get_frame().size().height as usize; + terminal.draw(move |frame| { + let size = frame.size(); + frame.render_widget( + Paragraph::new(lines) + .block( + Block::default() + .border_style(Style::default().fg(Color::Yellow)) + .title(format!("[{pid}]")) + .title( + block::Title::from(format!( + "[lines {}-{}]", + ui.scroll, + ui.scroll + ui.height + )) + .position(block::Position::Bottom) + .alignment(Alignment::Right), + ) + .borders(Borders::ALL), + ) + .scroll((ui.scroll as u16, 0)), + size, + ); + })?; + should_quit = handle_events(&mut ui)?; + } + + disable_raw_mode()?; + stdout().execute(LeaveAlternateScreen)?; + + Ok(()) +} |