crossterm/cursor/sys/
unix.rsuse std::{
io::{self, Error, ErrorKind, Write},
time::Duration,
};
use crate::{
event::{filter::CursorPositionFilter, poll_internal, read_internal, InternalEvent},
terminal::{disable_raw_mode, enable_raw_mode, sys::is_raw_mode_enabled},
Result,
};
pub fn position() -> Result<(u16, u16)> {
if is_raw_mode_enabled() {
read_position_raw()
} else {
read_position()
}
}
fn read_position() -> Result<(u16, u16)> {
enable_raw_mode()?;
let pos = read_position_raw();
disable_raw_mode()?;
pos
}
fn read_position_raw() -> Result<(u16, u16)> {
let mut stdout = io::stdout();
stdout.write_all(b"\x1B[6n")?;
stdout.flush()?;
loop {
match poll_internal(Some(Duration::from_millis(2000)), &CursorPositionFilter) {
Ok(true) => {
if let Ok(InternalEvent::CursorPosition(x, y)) =
read_internal(&CursorPositionFilter)
{
return Ok((x, y));
}
}
Ok(false) => {
return Err(Error::new(
ErrorKind::Other,
"The cursor position could not be read within a normal duration",
));
}
Err(_) => {}
}
}
}