Windows colorize (#486)

* Fix Windows terminal-colors
This commit is contained in:
John Kerl 2021-04-08 01:50:45 +01:00 committed by GitHub
parent e4b7ebb97a
commit fe204e9fa3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 48 deletions

View file

@ -1,2 +1,2 @@
map \d :w<C-m>:!clear;echo Building ...; echo; build-go<C-m>
map \d :w<C-m>:!clear;echo Building ...; echo; go build mlr.go<C-m>
map \f :w<C-m>:!clear;echo Building ...; echo; build; echo; main<C-m>

View file

@ -10,7 +10,7 @@ import (
"os"
"strings"
"github.com/fatih/color"
"miller/src/platform"
)
const DefaultPath = "./reg-test/cases"
@ -22,11 +22,6 @@ const ShouldFailSuffix = ".should-fail"
const MajorSeparator = "================================================================"
const MinorSeparator = "----------------------------------------------------------------"
var PASS = color.HiGreenString("PASS")
var pass = color.HiGreenString("pass")
var FAIL = color.HiRedString("FAIL")
var fail = color.HiRedString("fail")
// ----------------------------------------------------------------
type RegTester struct {
exeName string
@ -129,10 +124,12 @@ func (this *RegTester) Execute(
fmt.Println()
if this.casePassCount > 0 && this.caseFailCount == 0 {
fmt.Printf("%s overall\n", PASS)
platform.PrintHiGreen("PASS")
fmt.Printf(" overall\n")
return true
} else {
fmt.Printf("%s overall\n", FAIL)
platform.PrintHiRed("FAIL")
fmt.Printf(" overall\n")
return false
}
}
@ -214,9 +211,11 @@ func (this *RegTester) executeSingleDirectory(
// multiply announce.
if hasDirectEntries {
if passed {
fmt.Printf("%s %s/\n", PASS, dirName)
platform.PrintHiGreen("PASS")
fmt.Printf(" %s/\n", dirName)
} else {
fmt.Printf("%s %s/\n", FAIL, dirName)
platform.PrintHiRed("FAIL")
fmt.Printf(" %s/\n", dirName)
}
}
}
@ -433,9 +432,11 @@ func (this *RegTester) executeSingleCmdFile(
if verbosityLevel >= 1 {
if passed {
fmt.Printf("%s %s\n", pass, cmdFileName)
platform.PrintHiGreen("pass")
fmt.Printf(" %s\n", cmdFileName)
} else {
fmt.Printf("%s %s\n", fail, cmdFileName)
platform.PrintHiGreen("fail")
fmt.Printf(" %s\n", cmdFileName)
}
}

View file

@ -1,13 +1,15 @@
// ================================================================
// This is for doing color-highlighting for on-line help
// This is for doing color-highlighting for on-line help. This is a thin layer
// over the package is uses -- the value-add here is to centralize the choice
// of particular color (as of this writing, red) all in one spot.
// ================================================================
package repl
import (
"github.com/fatih/color"
"miller/src/platform"
)
func HighlightString(input string) string {
return color.HiRedString(input)
func PrintHighlightString(input string) {
platform.PrintHiRed(input)
}

View file

@ -823,29 +823,29 @@ func handleHelpSingle(this *Repl, arg string) {
if i > 0 {
fmt.Println()
}
fmt.Printf("%s: \n", HighlightString(strings.Join(entry.verbNames, " or ")))
PrintHighlightString(strings.Join(entry.verbNames, " or "))
entry.usageFunc(this)
}
return
}
if arg == "prompt" {
fmt.Printf(
"You can export the environment variable %s to customize the Miller REPL prompt.\n",
HighlightString(ENV_PRIMARY_PROMPT),
)
fmt.Printf(
"Otherwise, it defaults to \"%s\".\n",
HighlightString(DEFAULT_PRIMARY_PROMPT),
)
fmt.Printf(
"Likewise you can export the environment variable %s to customize the secondary prompt,\n",
HighlightString(ENV_SECONDARY_PROMPT),
)
fmt.Printf(
"which defaults to \"%s\". This is used for multi-line input.\n",
HighlightString(DEFAULT_SECONDARY_PROMPT),
)
fmt.Printf("You can export the environment variable ")
PrintHighlightString(ENV_PRIMARY_PROMPT)
fmt.Printf(" to customize the Miller REPL prompt.\n")
fmt.Printf("Otherwise, it defaults to \"")
PrintHighlightString(DEFAULT_PRIMARY_PROMPT)
fmt.Printf("\".\n")
fmt.Printf("Likewise you can export the environment variable ")
PrintHighlightString(ENV_SECONDARY_PROMPT)
fmt.Printf(" to customize the secondary prompt,\n")
fmt.Printf("which defaults to \"")
PrintHighlightString(DEFAULT_SECONDARY_PROMPT)
fmt.Printf("\". This is used for multi-line input.\n")
return
}
@ -857,7 +857,7 @@ func handleHelpSingle(this *Repl, arg string) {
if arg == "function-details" {
cst.BuiltinFunctionManagerInstance.ListBuiltinFunctionUsagesDecorated(
os.Stdout,
func(functionName string) string { return HighlightString(functionName) },
func(functionName string) { PrintHighlightString(functionName) },
)
return
}
@ -876,13 +876,13 @@ func handleHelpSingle(this *Repl, arg string) {
}
func showREPLIntro(this *Repl) {
fmt.Printf("%s\n", HighlightString("What the Miller REPL is:"))
PrintHighlightString("What the Miller REPL is:\n")
fmt.Println(
`The Miller REPL (read-evaluate-print loop) is an interactive counterpart
to record-processing using the put/filter DSL (domain-specific language).`)
fmt.Println()
fmt.Printf("%s\n", HighlightString("Using Miller without the REPL:"))
PrintHighlightString("Using Miller without the REPL:\n")
fmt.Printf(
`Using put and filter, you can do the following:
* Specify input format (e.g. --icsv), output format (e.g. --ojson), etc. using
@ -898,7 +898,7 @@ to record-processing using the put/filter DSL (domain-specific language).`)
fmt.Println()
fmt.Println()
fmt.Printf("%s\n", HighlightString("Using Miller with the REPL:"))
PrintHighlightString("Using Miller with the REPL:\n")
fmt.Println(
`Using the REPL, by contrast, you get interactive control over those same steps:
* Specify input format (e.g. --icsv), output format (e.g. --ojson), etc. using
@ -935,7 +935,7 @@ included in the output-record stream. But here in the REPL, they are simply
printed to the terminal, e.g. if you type '1+2', you will see '3'.`)
fmt.Println()
fmt.Printf("%s\n", HighlightString("Entering multi-line statements:"))
PrintHighlightString("Entering multi-line statements:\n")
fmt.Println(
`* To enter multi-line statements, enter '<' on a line by itself, then the code (taking care
for semicolons), then ">" on a line by itself. These will be executed immediately.
@ -944,20 +944,20 @@ printed to the terminal, e.g. if you type '1+2', you will see '3'.`)
':main', as if you had done ':load' to load statements from a file.`)
fmt.Println()
fmt.Printf("%s\n", HighlightString("History-editing:"))
PrintHighlightString("History-editing:\n")
fmt.Println(
`No command-line-history-editing feature is built in but 'rlwrap mlr repl' is a
delight. You may need 'brew install rlwrap', 'sudo apt-get install rlwrap',
etc. depending on your platform.`)
fmt.Println()
fmt.Printf("%s\n", HighlightString("On-line help:"))
PrintHighlightString("On-line help:\n")
fmt.Println("Type ':help' to see more about your options. In particular, ':help examples'.")
}
// ----------------------------------------------------------------
func showREPLExamples(this *Repl) {
fmt.Printf("%s\n", HighlightString("Immediately executed statements:"))
PrintHighlightString("Immediately executed statements:\n")
fmt.Println(
`[mlr] 1+2
3
@ -967,7 +967,7 @@ func showREPLExamples(this *Repl) {
[mlr] x+y
7`)
fmt.Println()
fmt.Printf("%s\n", HighlightString("Defining functions:"))
PrintHighlightString("Defining functions:\n")
fmt.Println(
`[mlr] <
func f(a,b) {
@ -977,7 +977,7 @@ func f(a,b) {
[mlr] f(7,5)
16807`)
fmt.Println()
fmt.Printf("%s\n", HighlightString("Reading and processing records:"))
PrintHighlightString("Reading and processing records:\n")
fmt.Println(
`[mlr] :open foo.dat
[mlr] :read

View file

@ -1543,7 +1543,7 @@ func (this *BuiltinFunctionManager) ListBuiltinFunctionsRaw(o *os.File) {
func (this *BuiltinFunctionManager) ListBuiltinFunctionUsages(o *os.File) {
this.ListBuiltinFunctionUsagesDecorated(
o,
func(functionName string) string { return functionName }, // no decoration
func(functionName string) { fmt.Print(functionName) }, // no decoration
)
}
@ -1552,15 +1552,15 @@ func (this *BuiltinFunctionManager) ListBuiltinFunctionUsages(o *os.File) {
// -- capitalization, ANSI color, etc.
func (this *BuiltinFunctionManager) ListBuiltinFunctionUsagesDecorated(
o *os.File,
nameDecorator func(string) string,
nameEmitter func(string),
) {
for i, builtinFunctionInfo := range *this.lookupTable {
if i > 0 {
fmt.Fprintln(o)
}
lib.InternalCodingErrorIf(builtinFunctionInfo.help == "")
fmt.Fprintf(o, "%-s (class=%s #args=%s) %s\n",
nameDecorator(builtinFunctionInfo.name),
nameEmitter(builtinFunctionInfo.name)
fmt.Fprintf(o, " (class=%s #args=%s) %s\n",
builtinFunctionInfo.class,
describeNargs(&builtinFunctionInfo),
builtinFunctionInfo.help,

21
go/src/platform/colors.go Normal file
View file

@ -0,0 +1,21 @@
package platform
import (
"fmt"
"github.com/fatih/color"
)
// Outside of Windows, we don't need the Fprintf to color.Output (and in fact
// color.Output is simply os.Stdout inside fatih/color). But inside Windows we
// do. That's why these functions take a string and print it, returning void --
// rather than taking a string and color-decorating it and returning the
// decoration as a string.
func PrintHiGreen(s string) {
fmt.Fprintf(color.Output, color.HiGreenString(s))
}
func PrintHiRed(s string) {
fmt.Fprintf(color.Output, color.HiRedString(s))
}