diff options
author | Andrew Gallant <jamslam@gmail.com> | 2018-02-10 18:42:35 -0500 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2018-02-10 22:28:12 -0500 |
commit | 2d68054b1da6ba7515118bbe98c80e4c5330cad5 (patch) | |
tree | f7dfd61d36b36c1dbf86427e17258f303044b8a9 /wincolor | |
parent | 65a63788bc2e785b879493725283d1a22e314bf2 (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.rs | 20 |
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(()) |