use anyhow::{Context, Result};
use crossterm::cursor::Show;
use crossterm::execute;
use crossterm::terminal::{self, disable_raw_mode, enable_raw_mode};
use crossterm::tty::IsTty;
use std::io::{self, Write};
const ARROW: &str = "→";
fn use_color() -> bool {
io::stderr().is_tty() && std::env::var_os("NO_COLOR").is_none()
}
pub fn status(msg: &str) {
if use_color() {
eprint!("\x1b[36m{}\x1b[0m {}\r\n", ARROW, msg);
} else {
eprint!("{} {}\r\n", ARROW, msg);
}
}
pub fn status_dim(msg: &str) {
if use_color() {
eprint!("\x1b[2m {}\x1b[0m\r\n", msg);
} else {
eprint!(" {}\r\n", msg);
}
}
pub struct RawModeGuard {
was_raw: bool,
}
impl RawModeGuard {
pub fn enter() -> Result<Self> {
enable_raw_mode().context("Failed to enable raw mode")?;
Ok(Self { was_raw: true })
}
}
impl Drop for RawModeGuard {
fn drop(&mut self) {
if self.was_raw {
let _ = disable_raw_mode();
let _ = execute!(io::stdout(), Show);
}
}
}
pub fn get_size() -> Result<(u16, u16)> {
let (cols, rows) = terminal::size().context("Failed to get terminal size")?;
Ok((cols, rows))
}
pub fn write_stdout(data: &[u8]) -> io::Result<()> {
let mut stdout = io::stdout().lock();
stdout.write_all(data)?;
stdout.flush()?;
Ok(())
}