blob: 026fba52d9f99484dc444a6c01aaa949533a6371 [file] [log] [blame]
use crossterm_winapi::ConsoleMode;
use winapi::um::wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
use lazy_static::lazy_static;
use crate::Result;
/// Toggle virtual terminal processing.
///
/// This method attempts to toggle virtual terminal processing for this
/// console. If there was a problem toggling it, then an error returned.
/// On success, the caller may assume that toggling it was successful.
///
/// When virtual terminal processing is enabled, characters emitted to the
/// console are parsed for VT100 and similar control character sequences
/// that control color and other similar operations.
pub(crate) fn set_virtual_terminal_processing(yes: bool) -> Result<()> {
let mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
let console_mode = ConsoleMode::new()?;
let old_mode = console_mode.mode()?;
let new_mode = if yes {
old_mode | mask
} else {
old_mode & !mask
};
if old_mode != new_mode {
console_mode.set_mode(new_mode)?;
}
Ok(())
}
lazy_static! {
static ref SUPPORTS_ANSI_ESCAPE_CODES: bool = {
// Some terminals on windows like GitBash can't use WinaApi calls directly
// so when we try to enable the ANSI-flag for windows this won't work.
// Because of that we should check first if the TERM-variable is set
// and see if the current terminal is a terminal who does support ANSI.
if is_specific_term() {
true
} else {
// if it is not listed we should try with WinApi to check if we do support ANSI-codes.
set_virtual_terminal_processing(true)
.map(|_| true)
.unwrap_or(false)
}
};
}
pub fn supports_ansi() -> bool {
*SUPPORTS_ANSI_ESCAPE_CODES
}
// Checks if the 'TERM' environment variable is set to check if the terminal supports ANSI-codes.
// I got the list of terminals from here: https://github.com/keqingrong/supports-ansi/blob/master/index.js
fn is_specific_term() -> bool {
const TERMS: [&str; 15] = [
"xterm", // xterm, PuTTY, Mintty
"rxvt", // RXVT
"eterm", // Eterm
"screen", // GNU screen, tmux
"tmux", // tmux
"vt100", "vt102", "vt220", "vt320", // DEC VT series
"ansi", // ANSI
"scoansi", // SCO ANSI
"cygwin", // Cygwin, MinGW
"linux", // Linux console
"konsole", // Konsole
"bvterm", // Bitvise SSH Client
];
match std::env::var("TERM") {
Ok(val) => val != "dumb" || TERMS.contains(&val.as_str()),
Err(_) => false,
}
}