Skip to content
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

add config option HighlightValues for adding colour/color to output #99

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions spew/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ var (
closeMapBytes = []byte("]")
lenEqualsBytes = []byte("len=")
capEqualsBytes = []byte("cap=")
highlight1StartBytes = []byte("\x1b[32m")
highlight2StartBytes = []byte("\x1b[33m")
highlight3StartBytes = []byte("\x1b[34m")
highlight4StartBytes = []byte("\x1b[36m")
highlightEndBytes = []byte("\x1b[0m")
)

// hexDigits is used to map a decimal value to a hex digit.
Expand Down
4 changes: 4 additions & 0 deletions spew/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ type ConfigState struct {
// be spewed to strings and sorted by those strings. This is only
// considered if SortKeys is true.
SpewKeys bool

// HighlightValues adds colour/color to scalar values in output.
// The colours are suitable for ANSI displays.
HighlightValues bool
}

// Config is the active configuration of the top-level functions.
Expand Down
4 changes: 4 additions & 0 deletions spew/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ The following configuration options are available:
spewed to strings and sorted by those strings. This is only
considered if SortKeys is true.

* HighlightValues
When true, values in dumps are highlighted using colours/colors
suitable for ANSI-compatible displays.

Dump Usage

Simply call spew.Dump with a list of variables you want to dump:
Expand Down
24 changes: 24 additions & 0 deletions spew/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,26 @@ func (d *dumpState) dump(v reflect.Value) {
}
}

highlightIsOn := false
if d.cs.HighlightValues {
switch kind {
case reflect.String:
highlightIsOn = true
d.w.Write(highlight1StartBytes)
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int,
reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint,
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
highlightIsOn = true
d.w.Write(highlight2StartBytes)
case reflect.Bool:
highlightIsOn = true
d.w.Write(highlight3StartBytes)
case reflect.Uintptr, reflect.UnsafePointer, reflect.Chan, reflect.Func:
highlightIsOn = true
d.w.Write(highlight4StartBytes)
}
}

switch kind {
case reflect.Invalid:
// Do nothing. We should never get here since invalid has already
Expand Down Expand Up @@ -446,6 +466,10 @@ func (d *dumpState) dump(v reflect.Value) {
fmt.Fprintf(d.w, "%v", v.String())
}
}

if highlightIsOn {
d.w.Write(highlightEndBytes)
}
}

// fdump is a helper function to consolidate the logic from the various public
Expand Down
56 changes: 56 additions & 0 deletions spew/dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ package spew_test
import (
"bytes"
"fmt"
"regexp"
"testing"
"unsafe"

Expand Down Expand Up @@ -1040,3 +1041,58 @@ func TestDumpSortedKeys(t *testing.T) {
}

}

func TestDumpHighlightValues(t *testing.T) {
cfg := spew.ConfigState{SortKeys: true, HighlightValues: true}
col := map[string]string{
"reset": "\x1b[0m",
"str": "\x1b[32m",
"num": "\x1b[33m",
"bool": "\x1b[34m",
"other": "\x1b[36m",
}
s := cfg.Sdump(map[int]string{1: "1", 3: "3", 2: "2"})
expected := "(map[int]string) (len=3) {\n" +
"(int) " + col["num"] + "1" + col["reset"] + ": (string) (len=1) " + col["str"] + "\"1\"" + col["reset"] + ",\n" +
"(int) " + col["num"] + "2" + col["reset"] + ": (string) (len=1) " + col["str"] + "\"2\"" + col["reset"] + ",\n" +
"(int) " + col["num"] + "3" + col["reset"] + ": (string) (len=1) " + col["str"] + "\"3\"" + col["reset"] + "\n" +
"}\n"
if s != expected {
t.Errorf("Highlighted string mismatch:\n %v %v", s, expected)
}

s = cfg.Sdump(map[stringer]int{"1": 1, "3": 3, "2": 2})
expected = "(map[spew_test.stringer]int) (len=3) {\n" +
"(spew_test.stringer) (len=1) stringer 1: (int) " + col["num"] + "1" + col["reset"] + ",\n" +
"(spew_test.stringer) (len=1) stringer 2: (int) " + col["num"] + "2" + col["reset"] + ",\n" +
"(spew_test.stringer) (len=1) stringer 3: (int) " + col["num"] + "3" + col["reset"] + "\n" +
"}\n"
if s != expected {
t.Errorf("Highlighted ints mismatch:\n %v %v", s, expected)
}

s = cfg.Sdump(map[string]bool{"custom1": true, "custom2": false})
expected = "(map[string]bool) (len=2) {\n" +
"(string) (len=7) " + col["str"] + `"custom1"` + col["reset"] + ": (bool) " + col["bool"] + "true" + col["reset"] + ",\n" +
"(string) (len=7) " + col["str"] + `"custom2"` + col["reset"] + ": (bool) " + col["bool"] + "false" + col["reset"] + "\n" +
"}\n"
if s != expected {
t.Errorf("Highlighted keys mismatch:\n %v %v", s, expected)
}

s = cfg.Sdump(map[string]chan int{"chanInt1": make(chan int), "chanInt2": make(chan int)})
dummyPtr := "0x123456789a"
expected = "(map[string]chan int) (len=2) {\n" +
"(string) (len=8) " + col["str"] + `"chanInt1"` + col["reset"] + ": (chan int) " + col["other"] + dummyPtr + col["reset"] + ",\n" +
"(string) (len=8) " + col["str"] + `"chanInt2"` + col["reset"] + ": (chan int) " + col["other"] + dummyPtr + col["reset"] + "\n" +
"}\n"

// replace all pointers with dummyPtr (they will be prefixed by 'm' - from col[], so cannot \b at start) to match expected
re := regexp.MustCompile(`0x[0-9a-f]{10}\b`)
s = re.ReplaceAllString(s, dummyPtr)

if s != expected {
t.Errorf("Highlighted other mismatch:\n %v %v", s, expected)
}

}