From ba35c340fa81f6ceeca8cfc349f5e2e9ae764f90 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 23 Jan 2024 13:21:11 +0100 Subject: [PATCH] Added a function that reads a key with cursor hidden --- src/term.rs | 14 ++++++++++++-- src/unix_term.rs | 13 ++++++++++++- src/wasm_term.rs | 2 +- src/windows_term/mod.rs | 4 ++-- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/term.rs b/src/term.rs index 44e94055..df0f9034 100644 --- a/src/term.rs +++ b/src/term.rs @@ -292,15 +292,25 @@ impl Term { if !self.is_tty { Ok(Key::Unknown) } else { - read_single_key(false) + read_single_key(false, false) } } + /// Like [`read_key`](Self::read_key) but disables the cursor. + pub fn read_key_no_cursor(&self) -> io::Result { + if !self.is_tty { + Ok(Key::Unknown) + } else { + read_single_key(false, true) + } + } + + /// Like [`read_key`](Self::read_key) but it can catch `CtrlC`. pub fn read_key_raw(&self) -> io::Result { if !self.is_tty { Ok(Key::Unknown) } else { - read_single_key(true) + read_single_key(true, false) } } diff --git a/src/unix_term.rs b/src/unix_term.rs index 271709f2..0f627f1a 100644 --- a/src/unix_term.rs +++ b/src/unix_term.rs @@ -294,7 +294,7 @@ fn read_single_key_impl(fd: i32) -> Result { } } -pub fn read_single_key(ctrlc_key: bool) -> io::Result { +pub fn read_single_key(ctrlc_key: bool, hide_cursor: bool) -> io::Result { let tty_f; let fd = unsafe { if libc::isatty(libc::STDIN_FILENO) == 1 { @@ -314,8 +314,19 @@ pub fn read_single_key(ctrlc_key: bool) -> io::Result { unsafe { libc::cfmakeraw(&mut termios) }; termios.c_oflag = original.c_oflag; c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSADRAIN, &termios) })?; + + if hide_cursor { + unsafe { + libc::write(fd, b"\x1b[?25l".as_ptr() as *const _, 6); + } + } let rv: io::Result = read_single_key_impl(fd); c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSADRAIN, &original) })?; + if hide_cursor { + unsafe { + libc::write(fd, b"\x1b[?25h".as_ptr() as *const _, 6); + } + } // if the user hit ^C we want to signal SIGINT to outselves. if let Err(ref err) = rv { diff --git a/src/wasm_term.rs b/src/wasm_term.rs index 13b844b2..618fa508 100644 --- a/src/wasm_term.rs +++ b/src/wasm_term.rs @@ -39,7 +39,7 @@ pub fn read_secure() -> io::Result { )) } -pub fn read_single_key(_ctrlc_key: bool) -> io::Result { +pub fn read_single_key(_ctrlc_key: bool, _hide_cursor: bool) -> io::Result { Err(io::Error::new( io::ErrorKind::Other, "unsupported operation", diff --git a/src/windows_term/mod.rs b/src/windows_term/mod.rs index 173f3ef5..3c6311f4 100644 --- a/src/windows_term/mod.rs +++ b/src/windows_term/mod.rs @@ -354,7 +354,7 @@ pub fn key_from_key_code(code: VIRTUAL_KEY) -> Key { pub fn read_secure() -> io::Result { let mut rv = String::new(); loop { - match read_single_key(false)? { + match read_single_key(false, false)? { Key::Enter => { break; } @@ -373,7 +373,7 @@ pub fn read_secure() -> io::Result { Ok(rv) } -pub fn read_single_key(_ctrlc_key: bool) -> io::Result { +pub fn read_single_key(_ctrlc_key: bool, _hide_cursor: bool) -> io::Result { let key_event = read_key_event()?; let unicode_char = unsafe { key_event.uChar.UnicodeChar };