termcolor: support ANSI in Windows terminals

This commit uses the new virtual terminal processing feature in Windows 10
to enable the use of ANSI escape codes to color ripgrep's output. This
technique is preferred over the console APIs because it seems like where
the future is heading, but also because it avoids needing to use an
intermediate buffer to deal with the Windows console in a multithreaded
environment.
This commit is contained in:
Andrew Gallant
2018-02-10 18:42:35 -05:00
parent 65a63788bc
commit 2d68054b1d
2 changed files with 30 additions and 13 deletions

View File

@@ -130,17 +130,23 @@ impl Console {
&mut self,
yes: bool,
) -> io::Result<()> {
let mut lpmode = 0;
let vt = wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
let mut old_mode = 0;
let handle = unsafe { processenv::GetStdHandle(self.handle_id) };
if unsafe { consoleapi::GetConsoleMode(handle, &mut lpmode) } == 0 {
if unsafe { consoleapi::GetConsoleMode(handle, &mut old_mode) } == 0 {
return Err(io::Error::last_os_error());
}
if yes {
lpmode |= wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
} else {
lpmode &= !wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
let new_mode =
if yes {
old_mode | vt
} else {
old_mode & !vt
};
if old_mode == new_mode {
return Ok(());
}
if unsafe { consoleapi::SetConsoleMode(handle, lpmode) } == 0 {
if unsafe { consoleapi::SetConsoleMode(handle, new_mode) } == 0 {
return Err(io::Error::last_os_error());
}
Ok(())