use base64::{Engine, engine::general_purpose};
use crossterm::{
Command, ExecutableCommand, cursor,
event::{DisableMouseCapture, EnableMouseCapture},
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
};
use std::io;
struct AlternateScreenGuard;
impl Drop for AlternateScreenGuard {
fn drop(&mut self) {
let _ = terminal::disable_raw_mode();
let mut stdout = io::stdout();
let _ = stdout.execute(DisableMouseCapture);
let _ = stdout.execute(cursor::Show);
let _ = stdout.execute(LeaveAlternateScreen);
}
}
pub fn with_alternate_screen<R, F>(f: F) -> io::Result<R>
where
F: FnOnce() -> io::Result<R>,
{
let mut stdout = io::stdout();
stdout.execute(EnterAlternateScreen)?;
let _guard = AlternateScreenGuard;
stdout.execute(EnableMouseCapture)?;
terminal::enable_raw_mode()?;
f()
}
struct SetClipboard {
content: String,
}
impl SetClipboard {
fn new(content: &str) -> Self {
Self {
content: general_purpose::STANDARD.encode(content.as_bytes()),
}
}
}
impl Command for SetClipboard {
fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
write!(f, "\x1b]52;c;{}\x1b\\", self.content)
}
#[cfg(windows)]
fn execute_winapi(&self) -> std::io::Result<()> {
Ok(())
}
}
pub fn copy_to_clipboard(text: &str) -> io::Result<()> {
use std::io::BufWriter;
let mut writer = BufWriter::new(io::stderr());
crossterm::execute!(writer, SetClipboard::new(text))
}