Skip to content

Commit

Permalink
lib/std/fs/File: enable VT seq support for Windows Console
Browse files Browse the repository at this point in the history
* Newer versions of Windows added VT seq support not only in Windows Terminal, but also in the old-fashioned Windows Console (standalone conhost.exe), though not enabled by default.
* Try setting the newer console mode flags provides better experience for Windows Console users.

Co-authored-by: Kexy Biscuit <[email protected]>
  • Loading branch information
Garfield550 and KexyBiscuit committed Jan 26, 2024
1 parent 34eaa93 commit cbc7aaa
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
21 changes: 18 additions & 3 deletions lib/std/fs/File.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion lib/std/os/windows/kernel32.zig
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +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 SetConsoleMode(in_hConsoleHandle: HANDLE, in_dwMode: DWORD) callconv(WINAPI) BOOL;

pub extern "kernel32" fn GetConsoleOutputCP() callconv(WINAPI) UINT;

Expand Down

0 comments on commit cbc7aaa

Please sign in to comment.