From 9b86fc5736a6a356e537db9baedd6c5f4a62d9fe Mon Sep 17 00:00:00 2001 From: Johan Walles Date: Sat, 17 Apr 2021 07:03:52 +0200 Subject: [PATCH] Windows: Color output, character input Arrow keys don't work. --- .gitignore | 1 + go.mod | 4 +++- go.sum | 2 ++ twin/screen-setup-windows.go | 23 ++++++++++++++++++++--- twin/screen-setup.go | 12 +++++++++++- twin/screen.go | 12 +----------- 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 0b74593..98e3c4c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /moar +/moar.exe /releases/moar-* diff --git a/go.mod b/go.mod index fa66fe8..5cc8792 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,9 @@ go 1.16 require ( github.com/alecthomas/chroma v0.8.2 github.com/google/go-cmp v0.5.5 // indirect - github.com/sirupsen/logrus v1.4.2 + github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect + github.com/sirupsen/logrus v1.8.1 + github.com/stretchr/objx v0.1.1 // indirect golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect golang.org/x/term v0.0.0-20210317153231-de623e64d2a6 gotest.tools v2.2.0+incompatible diff --git a/go.sum b/go.sum index 54db0b5..fcc745e 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= diff --git a/twin/screen-setup-windows.go b/twin/screen-setup-windows.go index adbfe44..f2b58f0 100644 --- a/twin/screen-setup-windows.go +++ b/twin/screen-setup-windows.go @@ -2,7 +2,12 @@ package twin -import "os" +import ( + "os" + + "golang.org/x/sys/windows" + "golang.org/x/term" +) func (screen *UnixScreen) setupSigwinchNotification() { screen.sigwinch = make(chan int, 1) @@ -12,10 +17,22 @@ func (screen *UnixScreen) setupSigwinchNotification() { // sigwinch.go for inspiration. } -func (screen *UnixScreen) setupTtyIn() { +func (screen *UnixScreen) setupTtyInTtyOut() { + // This won't work if we're getting data piped to us, contributions welcome. + screen.ttyIn = os.Stdin + + // Set input stream to raw mode var err error - screen.ttyIn, err = os.Open("CONIN$") + screen.oldTerminalState, err = term.MakeRaw(int(screen.ttyIn.Fd())) if err != nil { panic(err) } + + screen.ttyOut = os.Stdout + + // Enable console colors, from: https://stackoverflow.com/a/52579002 + stdout := windows.Handle(screen.ttyOut.Fd()) + var originalMode uint32 + windows.GetConsoleMode(stdout, &originalMode) + windows.SetConsoleMode(stdout, originalMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) } diff --git a/twin/screen-setup.go b/twin/screen-setup.go index d4c49ce..f4be782 100644 --- a/twin/screen-setup.go +++ b/twin/screen-setup.go @@ -8,6 +8,7 @@ import ( "syscall" log "github.com/sirupsen/logrus" + "golang.org/x/term" ) func (screen *UnixScreen) setupSigwinchNotification() { @@ -42,7 +43,7 @@ func (screen *UnixScreen) setupSigwinchNotification() { }() } -func (screen *UnixScreen) setupTtyIn() { +func (screen *UnixScreen) setupTtyInTtyOut() { // os.Stdout is a stream that goes to our terminal window. // // So if we read from there, we'll get input from the terminal window. @@ -52,4 +53,13 @@ func (screen *UnixScreen) setupTtyIn() { // // Tested on macOS and Linux, works like a charm! screen.ttyIn = os.Stdout // <- YES, WE SHOULD ASSIGN STDOUT TO TTYIN + + // Set input stream to raw mode + var err error + screen.oldTerminalState, err = term.MakeRaw(int(screen.ttyIn.Fd())) + if err != nil { + panic(err) + } + + screen.ttyOut = os.Stdout } diff --git a/twin/screen.go b/twin/screen.go index c1602c5..b3aaf2a 100644 --- a/twin/screen.go +++ b/twin/screen.go @@ -101,17 +101,7 @@ func NewScreen() (Screen, error) { screen.events = make(chan Event, 80) screen.setupSigwinchNotification() - - screen.setupTtyIn() - screen.ttyOut = os.Stdout - - // Set input stream to raw mode - var err error - screen.oldTerminalState, err = term.MakeRaw(int(screen.ttyIn.Fd())) - if err != nil { - panic(err) - } - + screen.setupTtyInTtyOut() screen.setAlternateScreenMode(true) screen.enableMouseTracking(true) screen.hideCursor(true)