Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

windows: add support for native virtual terminal #15206

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions lib/std/os.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Comment on lines +3202 to +3203
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like either 1. a version check should be used here or 2. an assertion should be added.

Copy link
Contributor Author

@perillo perillo Apr 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was to advertise this feature, but probably it is not necessary.

A version check is not necessary, since if SetConsoleMode returns 0, then the feature is not supported.

// 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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Does this affect the use case of using dumb as argument to the windows console?
  2. Did you compare how other applications are doing it, ie Windows Terminal? It sounds very fishy, that 2 kernel32 calls are necessary to query the console state.

Copy link
Contributor Author

@perillo perillo Apr 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Does this affect the use case of using dumb as argument to the windows console?

I'm not aware of any dumb arguments for the windows console. Note that I use Windows only for testing software compatibility.

2. Did you compare how other applications are doing it, ie [Windows Terminal](https://github.com/microsoft/terminal)? It sounds very fishy, that 2 kernel32 calls are necessary to query the console state.

AFAIK, Windows Terminal enables this the feature by default.

The problem, that I did not consider, is how to detect Windows Terminal.
With the current PR, escape codes will be disabled (not tested) when a Zig program runs on a Windows Terminal, since calling GetConsoleMode will fail (not tested).

See microsoft/terminal#1040.

Is anyone using Zig on a Windows Terminal?

Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Does this affect the use case of using dumb as argument to the windows console?

    1. Did you compare how other applications are doing it, ie Windows Terminal? It sounds very fishy, that 2 kernel32 calls are necessary to query the console state.

Note that the first call is to get the current state and the second it to set it. It is the same as with Unix termios.

Also, about the Console API and Windows Terminal: calling GetConsoleMode should not fail.

}
if (builtin.link_libc) {
return system.isatty(handle) != 0;
Expand Down
2 changes: 2 additions & 0 deletions lib/std/os/windows/kernel32.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down