summaryrefslogtreecommitdiffstats
path: root/wincolor
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2018-02-10 18:42:35 -0500
committerAndrew Gallant <jamslam@gmail.com>2018-02-10 22:28:12 -0500
commit2d68054b1da6ba7515118bbe98c80e4c5330cad5 (patch)
treef7dfd61d36b36c1dbf86427e17258f303044b8a9 /wincolor
parent65a63788bc2e785b879493725283d1a22e314bf2 (diff)
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.
Diffstat (limited to 'wincolor')
-rw-r--r--wincolor/src/win.rs20
1 files changed, 13 insertions, 7 deletions
diff --git a/wincolor/src/win.rs b/wincolor/src/win.rs
index 43ccdcdd..9542704c 100644
--- a/wincolor/src/win.rs
+++ b/wincolor/src/win.rs
@@ -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(())