diff options
Diffstat (limited to 'vendor/anstyle-query/src')
-rw-r--r-- | vendor/anstyle-query/src/lib.rs | 134 | ||||
-rw-r--r-- | vendor/anstyle-query/src/windows.rs | 78 |
2 files changed, 212 insertions, 0 deletions
diff --git a/vendor/anstyle-query/src/lib.rs b/vendor/anstyle-query/src/lib.rs new file mode 100644 index 0000000..4b3745a --- /dev/null +++ b/vendor/anstyle-query/src/lib.rs @@ -0,0 +1,134 @@ +pub mod windows; + +/// Check [CLICOLOR] status +/// +/// - When `true`, ANSI colors are supported and should be used when the program isn't piped, +/// similar to [`term_supports_color`] +/// - When `false`, don’t output ANSI color escape codes, similar to [`no_color`] +/// +/// See also: +/// - [terminfo](https://crates.io/crates/terminfo) or [term](https://crates.io/crates/term) for +/// checking termcaps +/// - [termbg](https://crates.io/crates/termbg) for detecting background color +/// +/// [CLICOLOR]: https://bixense.com/clicolors/ +#[inline] +pub fn clicolor() -> Option<bool> { + let value = std::env::var_os("CLICOLOR")?; + Some(value != "0") +} + +/// Check [CLICOLOR_FORCE] status +/// +/// ANSI colors should be enabled no matter what. +/// +/// [CLICOLOR_FORCE]: https://bixense.com/clicolors/ +#[inline] +pub fn clicolor_force() -> bool { + let value = std::env::var_os("CLICOLOR_FORCE"); + value + .as_deref() + .unwrap_or_else(|| std::ffi::OsStr::new("0")) + != "0" +} + +/// Check [NO_COLOR] status +/// +/// When `true`, should prevent the addition of ANSI color. +/// +/// User-level configuration files and per-instance command-line arguments should override +/// [NO_COLOR]. A user should be able to export `$NO_COLOR` in their shell configuration file as a +/// default, but configure a specific program in its configuration file to specifically enable +/// color. +/// +/// [NO_COLOR]: https://no-color.org/ +#[inline] +pub fn no_color() -> bool { + let value = std::env::var_os("NO_COLOR"); + value.as_deref().unwrap_or_else(|| std::ffi::OsStr::new("")) != "" +} + +/// Check `TERM` for color support +#[inline] +#[cfg(not(windows))] +pub fn term_supports_color() -> bool { + match std::env::var_os("TERM") { + // If TERM isn't set, then we are in a weird environment that + // probably doesn't support colors. + None => return false, + Some(k) => { + if k == "dumb" { + return false; + } + } + } + true +} + +/// Check `TERM` for color support +#[inline] +#[cfg(windows)] +pub fn term_supports_color() -> bool { + // On Windows, if TERM isn't set, then we shouldn't automatically + // assume that colors aren't allowed. This is unlike Unix environments + // where TERM is more rigorously set. + if let Some(k) = std::env::var_os("TERM") { + if k == "dumb" { + return false; + } + } + true +} + +/// Check `TERM` for ANSI color support +#[inline] +#[cfg(not(windows))] +pub fn term_supports_ansi_color() -> bool { + term_supports_color() +} + +/// Check `TERM` for ANSI color support +#[inline] +#[cfg(windows)] +pub fn term_supports_ansi_color() -> bool { + match std::env::var_os("TERM") { + // If TERM isn't set, then we are in a weird environment that + // probably doesn't support ansi. + None => return false, + Some(k) => { + // cygwin doesn't seem to support ANSI escape sequences + // and instead has its own variety. However, the Windows + // console API may be available. + if k == "dumb" || k == "cygwin" { + return false; + } + } + } + true +} + +/// Check [COLORTERM] for truecolor support +/// +/// [COLORTERM]: https://github.com/termstandard/colors +#[inline] +pub fn truecolor() -> bool { + let value = std::env::var_os("COLORTERM"); + let value = value.as_deref().unwrap_or_default(); + value == "truecolor" || value == "24bit" +} + +/// Report whether this is running in CI +/// +/// CI is a common environment where, despite being piped, ansi color codes are supported +/// +/// This is not as exhaustive as you'd find in a crate like `is_ci` but it should work in enough +/// cases. +#[inline] +pub fn is_ci() -> bool { + // Assuming its CI based on presence because who would be setting `CI=false`? + // + // This makes it easier to all of the potential values when considering our known values: + // - Gitlab and Github set it to `true` + // - Woodpecker sets it to `woodpecker` + std::env::var_os("CI").is_some() +} diff --git a/vendor/anstyle-query/src/windows.rs b/vendor/anstyle-query/src/windows.rs new file mode 100644 index 0000000..a8ce404 --- /dev/null +++ b/vendor/anstyle-query/src/windows.rs @@ -0,0 +1,78 @@ +//! Windows-specific style queries + +#[cfg(windows)] +mod windows_console { + use std::os::windows::io::AsRawHandle; + use std::os::windows::io::RawHandle; + + use windows_sys::Win32::System::Console::CONSOLE_MODE; + use windows_sys::Win32::System::Console::ENABLE_VIRTUAL_TERMINAL_PROCESSING; + + fn enable_vt(handle: RawHandle) -> std::io::Result<()> { + unsafe { + let handle = std::mem::transmute(handle); + if handle == 0 { + return Err(std::io::Error::new( + std::io::ErrorKind::BrokenPipe, + "console is detached", + )); + } + + let mut dwmode: CONSOLE_MODE = 0; + if windows_sys::Win32::System::Console::GetConsoleMode(handle, &mut dwmode) == 0 { + return Err(std::io::Error::last_os_error()); + } + + dwmode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if windows_sys::Win32::System::Console::SetConsoleMode(handle, dwmode) == 0 { + return Err(std::io::Error::last_os_error()); + } + + Ok(()) + } + } + + pub fn enable_virtual_terminal_processing() -> std::io::Result<()> { + let stdout = std::io::stdout(); + let stdout_handle = stdout.as_raw_handle(); + let stderr = std::io::stderr(); + let stderr_handle = stderr.as_raw_handle(); + + enable_vt(stdout_handle)?; + if stdout_handle != stderr_handle { + enable_vt(stderr_handle)?; + } + + Ok(()) + } + + #[inline] + pub(crate) fn enable_ansi_colors() -> Option<bool> { + Some( + enable_virtual_terminal_processing() + .map(|_| true) + .unwrap_or(false), + ) + } +} + +#[cfg(not(windows))] +mod windows_console { + #[inline] + pub(crate) fn enable_ansi_colors() -> Option<bool> { + None + } +} + +/// Enable ANSI escape codes (ENABLE_VIRTUAL_TERMINAL_PROCESSING) +/// +/// For non-windows systems, returns `None` +pub fn enable_ansi_colors() -> Option<bool> { + windows_console::enable_ansi_colors() +} + +/// Raw ENABLE_VIRTUAL_TERMINAL_PROCESSING on stdout/stderr +#[cfg(windows)] +pub fn enable_virtual_terminal_processing() -> std::io::Result<()> { + windows_console::enable_virtual_terminal_processing() +} |