Skip to content

Commit

Permalink
add sterm to wrap terminal handling gorp
Browse files Browse the repository at this point in the history
  • Loading branch information
jli committed Aug 22, 2021
1 parent 9f078df commit be6ab6b
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 15 deletions.
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use anyhow::Result;
use structopt::StructOpt;

// LEARN: why do i need to mention these here?
mod event;
mod render;
mod sproc;
mod sprocs;
mod sterm;
mod view;

use event::{Event, EventStream, Next};
Expand Down
66 changes: 66 additions & 0 deletions src/sterm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/// STerm: a wrapper around nitty-gritty terminal details.
use crossterm::execute;
use tui::backend::CrosstermBackend;
use tui::Terminal;

type CTBackend = CrosstermBackend<std::io::Stdout>;

// wrapper around tui and crossterm stuff
pub struct STerm {
terminal: Terminal<CTBackend>,
}

impl STerm {
pub fn new() -> Self {
let stdout = std::io::stdout();
let backend = CrosstermBackend::new(stdout);
let terminal = tui::Terminal::new(backend).expect("couldn't make tui::Terminal");
init_terminal();
STerm { terminal }
}

// proxying the only tui::Terminal methods needed. if we need more, maybe just
// use terminal directly.
pub fn clear(&mut self) -> std::io::Result<()> {
self.terminal.clear()
}

// LEARN: why doesn't this work? (error about sized types, etc)
// pub fn draw(&mut self, f: FnOnce(&mut tui::Frame<CTBackend>)) -> std::io::Result<()> {
pub fn draw<F>(&mut self, f: F) -> std::io::Result<()>
where
F: FnOnce(&mut tui::Frame<CTBackend>),
{
// LEARN: nicer way to throw away the Ok value?
self.terminal.draw(f).map(|_| ())
}
}

impl Drop for STerm {
fn drop(&mut self) {
restore_terminal();
}
}

// Note: zenith also does cursor::Hide and Clear in init, and Cursor::MoveTo,
// Clear, cursor::Show in restore, but those don't seem to be necessary with the
// alternative screen?

fn init_terminal() {
log::debug!("initializing STerm");
let mut sout = std::io::stdout();
// using an alternative screen prevents blank gap where the UI was rendering
execute!(sout, crossterm::terminal::EnterAlternateScreen)
.expect("Unable to enter alternate screen");
// needed to process key events as they come
crossterm::terminal::enable_raw_mode().expect("Unable to enter raw mode.");
}

fn restore_terminal() {
log::debug!("restoring STerm");
let mut sout = std::io::stdout();
execute!(sout, crossterm::terminal::LeaveAlternateScreen)
.expect("Unable to leave alternate screen.");
// fixes terminal offset weirdness
crossterm::terminal::disable_raw_mode().expect("Unable to disable raw mode");
}
21 changes: 6 additions & 15 deletions src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ use anyhow::Result;
use ordered_float::OrderedFloat as OrdFloat;

use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use tui::backend::CrosstermBackend;
use tui::layout::{Constraint, Layout};
use tui::style::{Modifier, Style};
use tui::widgets::{Block, Borders, Paragraph, Row, Table};
use tui::Terminal;

use crate::event::Next;
use crate::sterm::STerm;
use crate::{render, sproc::SProc};

#[derive(Copy, Clone, PartialEq)]
Expand Down Expand Up @@ -55,7 +54,7 @@ impl Dir {
}

pub struct View {
terminal: Terminal<CrosstermBackend<std::io::Stdout>>,
sterm: STerm,
sort_by: Metric,
sort_dir: Dir,
alert: Option<String>,
Expand All @@ -72,13 +71,8 @@ fn render_metric(m: f64) -> String {

impl View {
pub fn new() -> Result<Self> {
let stdout = std::io::stdout();
let backend = CrosstermBackend::new(stdout);
let terminal = tui::Terminal::new(backend)?;
// Needed to process key events as they come.
crossterm::terminal::enable_raw_mode()?;
Ok(Self {
terminal,
sterm: STerm::new(),
sort_by: Metric::Cpu,
sort_dir: Dir::Desc,
alert: None,
Expand Down Expand Up @@ -112,10 +106,7 @@ impl View {
KeyCode::Char('D') => self.sort_by = Metric::DiskTotal,
KeyCode::Char('I') => self.sort_dir.flip(),
KeyCode::Char('q') => {
// fixes terminal offset weirdness
crossterm::terminal::disable_raw_mode().unwrap();
// clear old state
self.terminal.clear().unwrap();
// note: terminal cleanup happens automatically via STerm::drop
next = Next::Quit;
}
KeyCode::Esc => (), // clear alert
Expand All @@ -142,8 +133,8 @@ impl View {
// erhm, borrow checker workarounds...
let alert = self.alert.clone();
let sort_by = self.sort_by.clone();
self.terminal.clear()?;
self.terminal.draw(|f| {
self.sterm.clear()?;
self.sterm.draw(|f| {
let main_constraints = if alert.is_some() {
vec![Constraint::Min(3), Constraint::Min(1)]
} else {
Expand Down

0 comments on commit be6ab6b

Please sign in to comment.