diff --git a/lib/std/fs/File.zig b/lib/std/fs/File.zig index b286380c851d..6996ab61fc04 100644 --- a/lib/std/fs/File.zig +++ b/lib/std/fs/File.zig @@ -219,9 +219,24 @@ pub fn isTty(self: File) bool { /// Test whether ANSI escape codes will be treated as such. pub fn supportsAnsiEscapeCodes(self: File) bool { if (builtin.os.tag == .windows) { - var console_mode: windows.DWORD = 0; - if (windows.kernel32.GetConsoleMode(self.handle, &console_mode) != 0) { - if (console_mode & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0) return true; + var original_console_mode: windows.DWORD = 0; + + // For Windows Terminal, VT Sequences processing is enabled by default. + if (windows.kernel32.GetConsoleMode(self.handle, &original_console_mode) != 0) { + if (original_console_mode & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0) return true; + + // For Windows Console, VT Sequences processing support was added in Windows 10 build 14361, but disabled by default. + // https://devblogs.microsoft.com/commandline/tmux-support-arrives-for-bash-on-ubuntu-on-windows/ + // Use Microsoft's recommended way to enable virtual terminal processing. + // https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#example-of-enabling-virtual-terminal-processing + var requested_console_modes: windows.DWORD = windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING | windows.DISABLE_NEWLINE_AUTO_RETURN; + var console_mode = original_console_mode | requested_console_modes; + if (windows.kernel32.SetConsoleMode(self.handle, console_mode) != 0) return true; + + // An application receiving ERROR_INVALID_PARAMETER with one of the newer console mode flags in the bit field should gracefully degrade behavior and try again. + requested_console_modes = windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING; + console_mode = original_console_mode | requested_console_modes; + if (windows.kernel32.SetConsoleMode(self.handle, console_mode) != 0) return true; } return posix.isCygwinPty(self.handle); diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index d48261a97ac3..faf1c01a0b2a 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -3733,6 +3733,7 @@ pub const CONSOLE_SCREEN_BUFFER_INFO = extern struct { }; pub const ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4; +pub const DISABLE_NEWLINE_AUTO_RETURN = 0x8; pub const FOREGROUND_BLUE = 1; pub const FOREGROUND_GREEN = 2; diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index a1ca655ed17c..fd06ba71cb16 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -165,6 +165,7 @@ pub extern "kernel32" fn GetCommandLineA() callconv(WINAPI) LPSTR; pub extern "kernel32" fn GetCommandLineW() callconv(WINAPI) LPWSTR; pub extern "kernel32" fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) callconv(WINAPI) BOOL; +pub extern "kernel32" fn SetConsoleMode(in_hConsoleHandle: HANDLE, in_dwMode: DWORD) callconv(WINAPI) BOOL; pub extern "kernel32" fn GetConsoleOutputCP() callconv(WINAPI) UINT;