-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Added msys2/cygwin terminal detection support #485
Conversation
log/term/terminal_windows_test.go
Outdated
} | ||
|
||
func TestIsTerminal(t *testing.T) { | ||
handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test directly fetches STDOUT using GetStdHandle
because go test
redirects its output (and so fails) but only if not run with -v
which makes for a surprising behavior otherwise !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add this as a comment in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
log/term/terminal_windows.go
Outdated
"syscall" | ||
"unsafe" | ||
|
||
"golang.org/x/sys/windows" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather avoid this enormous dependency since we're only using a few of its functions and they are not difficult to implement locally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this come with Go itself ?
I mainly used that instead of reinventing the wheel but I guess I can reimplement those in there if you think it is better form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it requires using go get
to retrieve and would need to be vendored by those that vendor their dependencies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I removed all the reference to external modules. I discovered that syscall
actually already has a lot of useful stuff we needed, including for handling UTF16 names (on which Windows heavily relies).
log/term/terminal_windows_test.go
Outdated
} | ||
|
||
func TestIsTerminal(t *testing.T) { | ||
handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add this as a comment in the code.
0ef6cea
to
c7967ca
Compare
I have verified that this PR fixes |
b11d065
to
4c2de73
Compare
@ChrisHines I changed everything you mentionned except for your last comment about Git bash. I will look at this right now. I noticed a weird behavior of All the code now uses only Let me know what you think of this. |
2dbbb85
to
ef721fa
Compare
Updated the PR to restore the behavior. I manually tested it with: https://gist.github.com/ereOn/32aafdf41c34b9749a90f464b2c96498. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks really nice. I'm glad you broke out IsConsole
and IsMSYSTerminal
because I thought that would be a good approach to make NewColorWriter
work well.
I've tested it in all three types of terminals and they all work great. I just have a few nits about the comments I'd like you to address and then we can merge this PR.
log/term/terminal_windows.go
Outdated
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fw.Fd(), uintptr(unsafe.Pointer(&st)), 0) | ||
return r != 0 && e == 0 | ||
|
||
// If the terminal is a Windows console, succeed right away. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment seems obsolete. I would say it's not needed anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. I had to push in a hurry, forgot about those comments. Fixed.
log/term/terminal_windows.go
Outdated
// If the terminal is a Windows console, succeed right away. | ||
err := syscall.GetConsoleMode(handle, &st) | ||
|
||
return (err == nil && st != 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to see a comment explaining st
and the significance of comparing it to 0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
log/term/terminal_windows.go
Outdated
return false | ||
} | ||
|
||
// The terminal is not a cmd.exe terminal, let's try to detect MSYS2 terminals. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear to me how we know it's not a cmd.exe terminal at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep indeed. That was a leftover too. Removed.
ef721fa
to
a62210c
Compare
@ChrisHines I addressed all the remaining comment issues. Thanks for the feedback ! |
Thanks for the contribution. Good work! |
This PR adds support for MSYS/Cygwin terminal support detection on Windows (#484).
The strategy for the regular terminal is still to use
GetConsoleMode
to detect the classiccmd.exe
console.If that fails, instead of failing directly, we now fallback to the following sequence:
io.Writer
's handle is a pipe handle, we move to 2.\\(cygwin|msys)-\w+-pty\d?-(to|from)-master
, MSYS/Cygwin terminal is detected and we returntrue
.If any of the two points above fails, we return
false
like the previous implementation.The exact same check is done in Vim, the popular UNIX text-editor.
I also added a test that validates (on Windows only) that STDOUT is detected as a terminal.