use std::{ io::Write, os::fd::AsRawFd, }; use crossterm::{ cursor::MoveTo, terminal::{EnterAlternateScreen, LeaveAlternateScreen}, ExecutableCommand, }; use crate::Result; pub(crate) struct AlternateScreen<'a, W> where W: Write + AsRawFd + Sized, { write: &'a mut W, } impl<'a, W> AlternateScreen<'a, W> where W: Write + AsRawFd + Sized, { pub(crate) fn new(write_handle: &'a mut W) -> Result { write_handle.execute(EnterAlternateScreen)?.execute(MoveTo(0, 0))?; Ok(Self { write: write_handle, }) } } impl Write for AlternateScreen<'_, W> where W: Write + AsRawFd + Sized, { fn write(&mut self, buf: &[u8]) -> std::io::Result { self.write.write(buf) } fn flush(&mut self) -> std::io::Result<()> { self.write.flush() } } impl AsRawFd for AlternateScreen<'_, W> where W: Write + AsRawFd + Sized, { fn as_raw_fd(&self) -> std::os::fd::RawFd { self.write.as_raw_fd() } } /* impl ExecutableCommand for AlternateScreen where W: Write + AsRawFd + Sized, { fn execute(&mut self, command: impl crossterm::Command) -> std::io::Result<&mut Self> { let mut write = self.write.lock().unwrap(); match write.execute(command) { Ok(_) => { drop(write); Ok(self) } Err(e) => Err(e), } } } */ impl Drop for AlternateScreen<'_, W> where W: Write + AsRawFd + Sized, { fn drop(&mut self) { self.write.execute(LeaveAlternateScreen).unwrap(); } }