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 Result,
10};
11
12pub fn position() -> Result<(u16, u16)> {
19 if is_raw_mode_enabled() {
20 read_position_raw()
21 } else {
22 read_position()
23 }
24}
25
26fn read_position() -> Result<(u16, u16)> {
27 enable_raw_mode()?;
28 let pos = read_position_raw();
29 disable_raw_mode()?;
30 pos
31}
32
33fn read_position_raw() -> Result<(u16, u16)> {
34 let mut stdout = io::stdout();
36 stdout.write_all(b"\x1B[6n")?;
37 stdout.flush()?;
38
39 loop {
40 match poll_internal(Some(Duration::from_millis(2000)), &CursorPositionFilter) {
41 Ok(true) => {
42 if let Ok(InternalEvent::CursorPosition(x, y)) =
43 read_internal(&CursorPositionFilter)
44 {
45 return Ok((x, y));
46 }
47 }
48 Ok(false) => {
49 return Err(Error::new(
50 ErrorKind::Other,
51 "The cursor position could not be read within a normal duration",
52 ));
53 }
54 Err(_) => {}
55 }
56 }
57}