use nu_protocol::{ShellError, Span, engine::Stack, shell_error::io::IoError};
#[must_use = "dropping the guard restores the previous raw-mode state"]
pub(crate) struct RawModeGuard {
leave_raw: bool,
}
impl RawModeGuard {
pub(crate) fn acquire(stack: &Stack, span: Span) -> Result<Self, ShellError> {
stack.require_stdin(span)?;
Self::enter(span)
}
pub(crate) fn enter(span: Span) -> Result<Self, ShellError> {
let was_raw = crossterm::terminal::is_raw_mode_enabled()
.map_err(|err| IoError::new(err, span, None))?;
if !was_raw {
crossterm::terminal::enable_raw_mode().map_err(|err| IoError::new(err, span, None))?;
}
Ok(Self { leave_raw: was_raw })
}
}
impl Drop for RawModeGuard {
fn drop(&mut self) {
if self.leave_raw {
reapply_raw_mode();
} else {
let _ = crossterm::terminal::disable_raw_mode();
}
}
}
fn reapply_raw_mode() {
let _ = crossterm::terminal::disable_raw_mode();
let _ = crossterm::terminal::enable_raw_mode();
}