Get Cursor UNIX improvement (#152)

This commit is contained in:
sigmaSd 2019-06-15 09:44:52 +01:00 committed by Timon
parent b95bf9901f
commit 216105aa06

View File

@ -1,5 +1,5 @@
use crossterm_utils::sys::unix::{self, RAW_MODE_ENABLED}; use crossterm_utils::sys::unix::{self, RAW_MODE_ENABLED};
use std::io::{self, Error, ErrorKind, Read, Write}; use std::io::{self, BufRead, Write};
/// Get the cursor position based on the current platform. /// Get the cursor position based on the current platform.
#[cfg(unix)] #[cfg(unix)]
@ -30,53 +30,42 @@ pub fn pos_raw() -> io::Result<(u16, u16)> {
// Where is the cursor? // Where is the cursor?
// Use `ESC [ 6 n`. // Use `ESC [ 6 n`.
let mut stdout = io::stdout(); let mut stdout = io::stdout();
let stdin = io::stdin();
// Write command // Write command
stdout.write_all(b"\x1B[6n")?; stdout.write_all(b"\x1B[6n")?;
stdout.flush()?; stdout.flush()?;
let mut buf = [0u8; 2]; stdin.lock().read_until(b'[', &mut vec![])?;
// Expect `ESC[` let mut rows = vec![];
io::stdin().read_exact(&mut buf)?; stdin.lock().read_until(b';', &mut rows).unwrap();
if buf[0] != 0x1B || buf[1] as char != '[' {
return Err(Error::new(ErrorKind::Other, "test"));
}
// Read rows and cols through a ad-hoc integer parsing function let mut cols = vec![];
let read_num: fn() -> Result<(i32, char), Error> = || -> Result<(i32, char), Error> { stdin.lock().read_until(b'R', &mut cols).unwrap();
let mut num = 0;
let mut c: char;
loop { // remove delimiter
let mut buf = [0u8; 1]; rows.pop();
io::stdin().read_exact(&mut buf)?; cols.pop();
c = buf[0] as char;
if let Some(d) = c.to_digit(10) {
num = if num == 0 { 0 } else { num * 10 };
num += d as i32;
} else {
break;
}
}
Ok((num, c)) let rows = rows
}; .into_iter()
.map(|b| (b as char))
.fold(String::new(), |mut acc, n| {
acc.push(n);
acc
})
.parse::<usize>()
.unwrap();
let cols = cols
.into_iter()
.map(|b| (b as char))
.fold(String::new(), |mut acc, n| {
acc.push(n);
acc
})
.parse::<usize>()
.unwrap();
// Read rows and expect `;`
let (rows, c) = read_num()?;
if c != ';' {
return Err(Error::new(ErrorKind::Other, "test"));
}
// Read cols
let (cols, c) = read_num()?;
// Expect `R`
if c == 'R' {
// subtract one to get 0-based coords
Ok(((cols - 1) as u16, (rows - 1) as u16)) Ok(((cols - 1) as u16, (rows - 1) as u16))
} else {
Err(Error::new(ErrorKind::Other, "test"))
}
} }