aboutsummaryrefslogtreecommitdiff
path: root/vendor/console/src/unix_term.rs
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2024-07-19 15:37:58 +0300
committerValentin Popov <valentin@popov.link>2024-07-19 15:37:58 +0300
commita990de90fe41456a23e58bd087d2f107d321f3a1 (patch)
tree15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/console/src/unix_term.rs
parent3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff)
downloadfparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz
fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip
Deleted vendor folder
Diffstat (limited to 'vendor/console/src/unix_term.rs')
-rw-r--r--vendor/console/src/unix_term.rs362
1 files changed, 0 insertions, 362 deletions
diff --git a/vendor/console/src/unix_term.rs b/vendor/console/src/unix_term.rs
deleted file mode 100644
index 8e1e592..0000000
--- a/vendor/console/src/unix_term.rs
+++ /dev/null
@@ -1,362 +0,0 @@
-use std::env;
-use std::fmt::Display;
-use std::fs;
-use std::io;
-use std::io::{BufRead, BufReader};
-use std::mem;
-use std::os::unix::io::AsRawFd;
-use std::ptr;
-use std::str;
-
-use crate::kb::Key;
-use crate::term::Term;
-
-pub use crate::common_term::*;
-
-pub const DEFAULT_WIDTH: u16 = 80;
-
-#[inline]
-pub fn is_a_terminal(out: &Term) -> bool {
- unsafe { libc::isatty(out.as_raw_fd()) != 0 }
-}
-
-pub fn is_a_color_terminal(out: &Term) -> bool {
- if !is_a_terminal(out) {
- return false;
- }
-
- if env::var("NO_COLOR").is_ok() {
- return false;
- }
-
- match env::var("TERM") {
- Ok(term) => term != "dumb",
- Err(_) => false,
- }
-}
-
-pub fn c_result<F: FnOnce() -> libc::c_int>(f: F) -> io::Result<()> {
- let res = f();
- if res != 0 {
- Err(io::Error::last_os_error())
- } else {
- Ok(())
- }
-}
-
-pub fn terminal_size(out: &Term) -> Option<(u16, u16)> {
- unsafe {
- if libc::isatty(libc::STDOUT_FILENO) != 1 {
- return None;
- }
-
- let mut winsize: libc::winsize = std::mem::zeroed();
-
- // FIXME: ".into()" used as a temporary fix for a libc bug
- // https://github.com/rust-lang/libc/pull/704
- #[allow(clippy::useless_conversion)]
- libc::ioctl(out.as_raw_fd(), libc::TIOCGWINSZ.into(), &mut winsize);
- if winsize.ws_row > 0 && winsize.ws_col > 0 {
- Some((winsize.ws_row as u16, winsize.ws_col as u16))
- } else {
- None
- }
- }
-}
-
-pub fn read_secure() -> io::Result<String> {
- let f_tty;
- let fd = unsafe {
- if libc::isatty(libc::STDIN_FILENO) == 1 {
- f_tty = None;
- libc::STDIN_FILENO
- } else {
- let f = fs::OpenOptions::new()
- .read(true)
- .write(true)
- .open("/dev/tty")?;
- let fd = f.as_raw_fd();
- f_tty = Some(BufReader::new(f));
- fd
- }
- };
-
- let mut termios = core::mem::MaybeUninit::uninit();
- c_result(|| unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) })?;
- let mut termios = unsafe { termios.assume_init() };
- let original = termios;
- termios.c_lflag &= !libc::ECHO;
- c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSAFLUSH, &termios) })?;
- let mut rv = String::new();
-
- let read_rv = if let Some(mut f) = f_tty {
- f.read_line(&mut rv)
- } else {
- io::stdin().read_line(&mut rv)
- };
-
- c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSAFLUSH, &original) })?;
-
- read_rv.map(|_| {
- let len = rv.trim_end_matches(&['\r', '\n'][..]).len();
- rv.truncate(len);
- rv
- })
-}
-
-fn poll_fd(fd: i32, timeout: i32) -> io::Result<bool> {
- let mut pollfd = libc::pollfd {
- fd,
- events: libc::POLLIN,
- revents: 0,
- };
- let ret = unsafe { libc::poll(&mut pollfd as *mut _, 1, timeout) };
- if ret < 0 {
- Err(io::Error::last_os_error())
- } else {
- Ok(pollfd.revents & libc::POLLIN != 0)
- }
-}
-
-#[cfg(target_os = "macos")]
-fn select_fd(fd: i32, timeout: i32) -> io::Result<bool> {
- unsafe {
- let mut read_fd_set: libc::fd_set = mem::zeroed();
-
- let mut timeout_val;
- let timeout = if timeout < 0 {
- ptr::null_mut()
- } else {
- timeout_val = libc::timeval {
- tv_sec: (timeout / 1000) as _,
- tv_usec: (timeout * 1000) as _,
- };
- &mut timeout_val
- };
-
- libc::FD_ZERO(&mut read_fd_set);
- libc::FD_SET(fd, &mut read_fd_set);
- let ret = libc::select(
- fd + 1,
- &mut read_fd_set,
- ptr::null_mut(),
- ptr::null_mut(),
- timeout,
- );
- if ret < 0 {
- Err(io::Error::last_os_error())
- } else {
- Ok(libc::FD_ISSET(fd, &read_fd_set))
- }
- }
-}
-
-fn select_or_poll_term_fd(fd: i32, timeout: i32) -> io::Result<bool> {
- // There is a bug on macos that ttys cannot be polled, only select()
- // works. However given how problematic select is in general, we
- // normally want to use poll there too.
- #[cfg(target_os = "macos")]
- {
- if unsafe { libc::isatty(fd) == 1 } {
- return select_fd(fd, timeout);
- }
- }
- poll_fd(fd, timeout)
-}
-
-fn read_single_char(fd: i32) -> io::Result<Option<char>> {
- // timeout of zero means that it will not block
- let is_ready = select_or_poll_term_fd(fd, 0)?;
-
- if is_ready {
- // if there is something to be read, take 1 byte from it
- let mut buf: [u8; 1] = [0];
-
- read_bytes(fd, &mut buf, 1)?;
- Ok(Some(buf[0] as char))
- } else {
- //there is nothing to be read
- Ok(None)
- }
-}
-
-// Similar to libc::read. Read count bytes into slice buf from descriptor fd.
-// If successful, return the number of bytes read.
-// Will return an error if nothing was read, i.e when called at end of file.
-fn read_bytes(fd: i32, buf: &mut [u8], count: u8) -> io::Result<u8> {
- let read = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut _, count as usize) };
- if read < 0 {
- Err(io::Error::last_os_error())
- } else if read == 0 {
- Err(io::Error::new(
- io::ErrorKind::UnexpectedEof,
- "Reached end of file",
- ))
- } else if buf[0] == b'\x03' {
- Err(io::Error::new(
- io::ErrorKind::Interrupted,
- "read interrupted",
- ))
- } else {
- Ok(read as u8)
- }
-}
-
-fn read_single_key_impl(fd: i32) -> Result<Key, io::Error> {
- loop {
- match read_single_char(fd)? {
- Some('\x1b') => {
- // Escape was read, keep reading in case we find a familiar key
- break if let Some(c1) = read_single_char(fd)? {
- if c1 == '[' {
- if let Some(c2) = read_single_char(fd)? {
- match c2 {
- 'A' => Ok(Key::ArrowUp),
- 'B' => Ok(Key::ArrowDown),
- 'C' => Ok(Key::ArrowRight),
- 'D' => Ok(Key::ArrowLeft),
- 'H' => Ok(Key::Home),
- 'F' => Ok(Key::End),
- 'Z' => Ok(Key::BackTab),
- _ => {
- let c3 = read_single_char(fd)?;
- if let Some(c3) = c3 {
- if c3 == '~' {
- match c2 {
- '1' => Ok(Key::Home), // tmux
- '2' => Ok(Key::Insert),
- '3' => Ok(Key::Del),
- '4' => Ok(Key::End), // tmux
- '5' => Ok(Key::PageUp),
- '6' => Ok(Key::PageDown),
- '7' => Ok(Key::Home), // xrvt
- '8' => Ok(Key::End), // xrvt
- _ => Ok(Key::UnknownEscSeq(vec![c1, c2, c3])),
- }
- } else {
- Ok(Key::UnknownEscSeq(vec![c1, c2, c3]))
- }
- } else {
- // \x1b[ and 1 more char
- Ok(Key::UnknownEscSeq(vec![c1, c2]))
- }
- }
- }
- } else {
- // \x1b[ and no more input
- Ok(Key::UnknownEscSeq(vec![c1]))
- }
- } else {
- // char after escape is not [
- Ok(Key::UnknownEscSeq(vec![c1]))
- }
- } else {
- //nothing after escape
- Ok(Key::Escape)
- };
- }
- Some(c) => {
- let byte = c as u8;
- let mut buf: [u8; 4] = [byte, 0, 0, 0];
-
- break if byte & 224u8 == 192u8 {
- // a two byte unicode character
- read_bytes(fd, &mut buf[1..], 1)?;
- Ok(key_from_utf8(&buf[..2]))
- } else if byte & 240u8 == 224u8 {
- // a three byte unicode character
- read_bytes(fd, &mut buf[1..], 2)?;
- Ok(key_from_utf8(&buf[..3]))
- } else if byte & 248u8 == 240u8 {
- // a four byte unicode character
- read_bytes(fd, &mut buf[1..], 3)?;
- Ok(key_from_utf8(&buf[..4]))
- } else {
- Ok(match c {
- '\n' | '\r' => Key::Enter,
- '\x7f' => Key::Backspace,
- '\t' => Key::Tab,
- '\x01' => Key::Home, // Control-A (home)
- '\x05' => Key::End, // Control-E (end)
- '\x08' => Key::Backspace, // Control-H (8) (Identical to '\b')
- _ => Key::Char(c),
- })
- };
- }
- None => {
- // there is no subsequent byte ready to be read, block and wait for input
- // negative timeout means that it will block indefinitely
- match select_or_poll_term_fd(fd, -1) {
- Ok(_) => continue,
- Err(_) => break Err(io::Error::last_os_error()),
- }
- }
- }
- }
-}
-
-pub fn read_single_key() -> io::Result<Key> {
- let tty_f;
- let fd = unsafe {
- if libc::isatty(libc::STDIN_FILENO) == 1 {
- libc::STDIN_FILENO
- } else {
- tty_f = fs::OpenOptions::new()
- .read(true)
- .write(true)
- .open("/dev/tty")?;
- tty_f.as_raw_fd()
- }
- };
- let mut termios = core::mem::MaybeUninit::uninit();
- c_result(|| unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) })?;
- let mut termios = unsafe { termios.assume_init() };
- let original = termios;
- unsafe { libc::cfmakeraw(&mut termios) };
- termios.c_oflag = original.c_oflag;
- c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSADRAIN, &termios) })?;
- let rv: io::Result<Key> = read_single_key_impl(fd);
- c_result(|| unsafe { libc::tcsetattr(fd, libc::TCSADRAIN, &original) })?;
-
- // if the user hit ^C we want to signal SIGINT to outselves.
- if let Err(ref err) = rv {
- if err.kind() == io::ErrorKind::Interrupted {
- unsafe {
- libc::raise(libc::SIGINT);
- }
- }
- }
-
- rv
-}
-
-pub fn key_from_utf8(buf: &[u8]) -> Key {
- if let Ok(s) = str::from_utf8(buf) {
- if let Some(c) = s.chars().next() {
- return Key::Char(c);
- }
- }
- Key::Unknown
-}
-
-#[cfg(not(target_os = "macos"))]
-lazy_static::lazy_static! {
- static ref IS_LANG_UTF8: bool = match std::env::var("LANG") {
- Ok(lang) => lang.to_uppercase().ends_with("UTF-8"),
- _ => false,
- };
-}
-
-#[cfg(target_os = "macos")]
-pub fn wants_emoji() -> bool {
- true
-}
-
-#[cfg(not(target_os = "macos"))]
-pub fn wants_emoji() -> bool {
- *IS_LANG_UTF8
-}
-
-pub fn set_title<T: Display>(title: T) {
- print!("\x1b]0;{}\x07", title);
-}