From 3454d74a4c8ac5c744770ebb3d61d8edd0e7b34d Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 12 May 2017 12:12:49 +0100 Subject: [PATCH] Enable ANSI colors on Windows 10 and newer --- terminal_windows.go | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/terminal_windows.go b/terminal_windows.go index 05d2f91..8871857 100644 --- a/terminal_windows.go +++ b/terminal_windows.go @@ -8,8 +8,13 @@ package logrus import ( + "bytes" + "errors" "io" "os" + "os/exec" + "strconv" + "strings" "syscall" "unsafe" ) @@ -18,8 +23,51 @@ var kernel32 = syscall.NewLazyDLL("kernel32.dll") var ( procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procSetConsoleMode = kernel32.NewProc("SetConsoleMode") ) +const ( + enableProcessedOutput = 0x0001 + enableWrapAtEolOutput = 0x0002 + enableVirtualTerminalProcessing = 0x0004 +) + +func getVersion() (float64, error) { + stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} + cmd := exec.Command("cmd", "ver") + cmd.Stdout = stdout + cmd.Stderr = stderr + err := cmd.Run() + if err != nil { + return -1, err + } + + version := strings.Replace(stdout.String(), "\n", "", -1) + version = strings.Replace(version, "\r\n", "", -1) + + x1 := strings.Index(version, "[Version") + + if x1 == -1 || strings.Index(version, "]") == -1 { + return -1, errors.New("Can't determine Windows version") + } + + return strconv.ParseFloat(version[x1+9:x1+13], 64) +} + +func init() { + ver, err := getVersion() + if err != nil { + panic(err) + } + + // Activate Virtual Processing for Windows CMD + // Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx + if ver >= 10 { + handle := syscall.Handle(os.Stderr.Fd()) + procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing) + } +} + // IsTerminal returns true if stderr's file descriptor is a terminal. func IsTerminal(f io.Writer) bool { switch v := f.(type) {