use std::io::{self, Write};
use std::time::Duration;
use anyhow::{Context, Result};
use ratatui::{
Terminal,
backend::Backend,
crossterm::{cursor::SetCursorStyle, execute},
};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub(crate) enum MousePointerShape {
#[default]
Default,
Pointer,
Text,
}
impl MousePointerShape {
fn as_osc22_name(self) -> &'static str {
match self {
Self::Default => "default",
Self::Pointer => "pointer",
Self::Text => "text",
}
}
}
pub(crate) fn set_mouse_pointer_shape(shape: MousePointerShape) {
let name = shape.as_osc22_name();
let mut stderr = io::stderr().lock();
let _ = write!(stderr, "\x1b]22;{name}\x07");
let _ = stderr.flush();
}
pub(crate) fn reset_mouse_pointer_shape() {
set_mouse_pointer_shape(MousePointerShape::Default);
}
pub(super) fn prepare_terminal<B: Backend>(terminal: &mut Terminal<B>) -> Result<()> {
terminal
.hide_cursor()
.map_err(|e| anyhow::anyhow!("failed to hide inline cursor: {}", e))?;
terminal
.clear()
.map_err(|e| anyhow::anyhow!("failed to clear inline terminal: {}", e))?;
Ok(())
}
pub(super) fn finalize_terminal<B: Backend>(terminal: &mut Terminal<B>) -> Result<()> {
execute!(io::stderr(), SetCursorStyle::DefaultUserShape)
.context("failed to restore cursor style after inline session")?;
reset_mouse_pointer_shape();
terminal
.show_cursor()
.map_err(|e| anyhow::anyhow!("failed to show cursor after inline session: {}", e))?;
terminal
.clear()
.map_err(|e| anyhow::anyhow!("failed to clear inline terminal after session: {}", e))?;
terminal
.flush()
.map_err(|e| anyhow::anyhow!("failed to flush inline terminal after session: {}", e))?;
Ok(())
}
pub(super) fn drain_terminal_events() {
use ratatui::crossterm::event;
while event::poll(Duration::from_millis(0)).unwrap_or(false) {
let _ = event::read();
}
}