From eb5070342558dc5a44373d38432806a3fb6e6052 Mon Sep 17 00:00:00 2001 From: Manlio Perillo Date: Sat, 8 Apr 2023 07:26:47 +0200 Subject: [PATCH] windows: add support for native virtual terminal The os.isatty function for windows supports the optional Cygwin (probably rarely used on recent Windows installation), but does not support the virtual terminal processing introduced in Windows 10 1511. Implement it. Add the SetConsoleMode function in kernel32, and define the constant ENABLE_VIRTUAL_TERMINAL_PROCESSING in isatty. --- lib/std/os.zig | 12 ++++++++++-- lib/std/os/windows/kernel32.zig | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index 36a54adde97c..1bf0e292157e 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -3199,8 +3199,16 @@ pub fn isatty(handle: fd_t) bool { if (isCygwinPty(handle)) return true; - var out: windows.DWORD = undefined; - return windows.kernel32.GetConsoleMode(handle, &out) != 0; + // Support for ANSI escapes sequences was added to Windows 10 1511 + // on 2016. + // See https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences. + const ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004; + + var mode: windows.DWORD = undefined; + if (windows.kernel32.GetConsoleMode(handle, &mode) == 0) return false; + + mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + return windows.kernel32.SetConsoleMode(handle, mode) != 0; } if (builtin.link_libc) { return system.isatty(handle) != 0; diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index 942d7ddba791..0167959f95df 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -320,6 +320,8 @@ pub extern "kernel32" fn RtlVirtualUnwind( ContextPointers: ?*KNONVOLATILE_CONTEXT_POINTERS, ) callconv(WINAPI) *EXCEPTION_ROUTINE; +pub extern "kernel32" fn SetConsoleMode(in_hConsoleHandle: HANDLE, in_Mode: DWORD) callconv(WINAPI) BOOL; + pub extern "kernel32" fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) callconv(WINAPI) BOOL; pub extern "kernel32" fn SetConsoleCtrlHandler(