crossterm/cursor/sys/
unix.rs1use std::{
2 io::{self, Error, ErrorKind, Write},
3 time::Duration,
4};
5
6use crate::{
7 event::{filter::CursorPositionFilter, poll_internal, read_internal, InternalEvent},
8 terminal::{disable_raw_mode, enable_raw_mode, sys::is_raw_mode_enabled},
9};
10
11pub fn position() -> io::Result<(u16, u16)> {
18 if is_raw_mode_enabled() {
19 read_position_raw()
20 } else {
21 read_position()
22 }
23}
24
25fn read_position() -> io::Result<(u16, u16)> {
26 enable_raw_mode()?;
27 let pos = read_position_raw();
28 disable_raw_mode()?;
29 pos
30}
31
32fn read_position_raw() -> io::Result<(u16, u16)> {
33 let mut stdout = io::stdout();
35 stdout.write_all(b"\x1B[6n")?;
36 stdout.flush()?;
37
38 loop {
39 match poll_internal(Some(Duration::from_millis(2000)), &CursorPositionFilter) {
40 Ok(true) => {
41 if let Ok(InternalEvent::CursorPosition(x, y)) =
42 read_internal(&CursorPositionFilter)
43 {
44 return Ok((x, y));
45 }
46 }
47 Ok(false) => {
48 return Err(Error::new(
49 ErrorKind::Other,
50 "The cursor position could not be read within a normal duration",
51 ));
52 }
53 Err(_) => {}
54 }
55 }
56}