Skip to content

Enable virtual terminal processing on Windows #511

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

Merged
merged 5 commits into from
Mar 12, 2025
Merged

Enable virtual terminal processing on Windows #511

merged 5 commits into from
Mar 12, 2025

Conversation

Sainan
Copy link
Contributor

@Sainan Sainan commented Mar 12, 2025

Before:
image

After:
image

Fixes #480

(I've never used Go before and I didn't verify this works on MacOS or Linux.)

@jakebailey
Copy link
Member

jakebailey commented Mar 12, 2025

I suspect that this code needs to be locked behind a build tag. It's illegal to use the windows syscall package on the wrong platform, even if conditional.

@jakebailey
Copy link
Member

For an example of how to do it, try looking at realpath_windows.go and realpath_other.go.

@Sainan
Copy link
Contributor Author

Sainan commented Mar 12, 2025

I was trying to avoid doing that because it would introduce new files, but done that now. Let me know if I should move or rename them.

var mode uint32
err = windows.GetConsoleMode(windows.Handle(hStdout), &mode)
if err == nil {
windows.SetConsoleMode(windows.Handle(hStdout), mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
Copy link
Member

Choose a reason for hiding this comment

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

Does Node do this by default? How was this working before?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, executing console.log("\x1B[38;2;255;0;0mTesting"); via Node shows that it works, so I assume Node just does that by default.

Copy link
Member

Choose a reason for hiding this comment

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

I don't see them doing in their code at all; the constant is defined but seeming unused...

Copy link
Contributor Author

@Sainan Sainan Mar 12, 2025

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Aha, thanks!

Copy link
Member

Choose a reason for hiding this comment

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

Alright, so checking this, uv__determine_vterm_state is only called when uv_tty_init is called; I get the feeling that Node only calls this when it knows the output is a TTY, via https://github.com/nodejs/node/blob/d615a3cfcbc357ccebd07a37fa0002fee162d9ce/src/tty_wrap.cc#L152, But I don't see this used either!

I wonder if there's just a plain package somewhere that sets ENABLE_VIRTUAL_TERMINAL_PROCESSING...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, as you've already seen with trying to locate ENABLE_VIRTUAL_TERMINAL_PROCESSING, Github's search results are not always conclusive.

I don't really know Node internals, but I can guarantee you that ENABLE_VIRTUAL_TERMINAL_PROCESSING does need to be set for ANSI escape sequences to work on Windows. (Although apparently not on Windows 11)

Copy link
Member

Choose a reason for hiding this comment

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

To be clear, I think this PR is right, at least how to enable it, but I'm just trying to verify we won't break something like LSP or piping where the output is not a TTY.

Given https://github.com/jedib0t/go-pretty/blob/b14745cbcf545d2704cdd6f97163344b0fe683a3/text/ansi_windows.go#L22 looks similar and does not appear to be conditional at all, so I very much suspect this PR is good as-is.

Copy link
Member

Choose a reason for hiding this comment

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

I checked, the LSP is totally fine. I'm going to approve this 😄

var mode uint32
err = windows.GetConsoleMode(windows.Handle(hStdout), &mode)
if err == nil {
windows.SetConsoleMode(windows.Handle(hStdout), mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
Copy link
Member

Choose a reason for hiding this comment

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

I checked, the LSP is totally fine. I'm going to approve this 😄

@jakebailey jakebailey added this pull request to the merge queue Mar 12, 2025
@jakebailey
Copy link
Member

Once again, thanks for sending this. I'm happy to see that your first time using Go was successful.

@Sainan
Copy link
Contributor Author

Sainan commented Mar 12, 2025

It's easier than ever to pick up a new language in the age of AI. ^^

Merged via the queue into microsoft:main with commit c7ed328 Mar 12, 2025
17 checks passed
@Sainan Sainan deleted the win-VT-mode branch March 12, 2025 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error messages don't seem coloured as expected on Windows
3 participants