Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
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
55 changes: 32 additions & 23 deletions pkg/color/coloring.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,33 +163,42 @@ func LookupColorByName(s string) (ColorCode, bool) {
}

// UnderlineSingleRune is a special-use-case colorer for headers with a single character called out
func HighlightSingleRune(word string, runeIndex int, base, highlight ColorCode) string {
func WriteHighlightSingleRune(w io.StringWriter, word string, runeIndex int, base, highlight ColorCode) {
if !Enabled {
return word
}

if runeIndex >= 0 && runeIndex < len(word) {
var sb strings.Builder
sb.Grow(len(word) * 2)

sb.WriteString(string(base))
idx := 0
for _, r := range word {
if idx == runeIndex {
sb.WriteString(string(highlight))
sb.WriteRune(r)
sb.WriteString(string(Reset + base))
} else {
sb.WriteRune(r)
}
idx++
}
sb.WriteString(string(Reset))
w.WriteString(word)
return
}

return sb.String()
w.WriteString(string(base))

offset, width := byteIndexOfRune(word, runeIndex)
if offset >= 0 {
w.WriteString(word[:offset])
w.WriteString(string(highlight))
w.WriteString(word[offset : offset+width])
w.WriteString(Reset)
w.WriteString(string(base))
w.WriteString(word[offset+width:])
} else {
w.WriteString(word)
}

return Wrap(base, word)
w.WriteString(Reset)
}

// returns byte index of a rune index within a string
//
// this is an optimization to allow finding a position of a rune in a string
// and then accessing it directly using string slices, preventing an alloc
func byteIndexOfRune(s string, runeIndex int) (offset, width int) {
rIdx := 0
for bIdx, r := range s {
if rIdx == runeIndex {
return bIdx, utf8.RuneLen(r)
}
rIdx++
}
return -1, -1
}

// StrLen ignoring any color codes. If color disabled, returns len(s)
Expand Down
16 changes: 16 additions & 0 deletions pkg/color/coloring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ func TestLookupColor(t *testing.T) {
}

func TestHighlightSingleRune(t *testing.T) {
HighlightSingleRune := func(word string, runeIndex int, base, highlight ColorCode) string {
var sb strings.Builder
WriteHighlightSingleRune(&sb, word, runeIndex, base, highlight)
return sb.String()
}

assert.Equal(t, "\x1b[34;1m\x1b[0m", HighlightSingleRune("", 0, BrightBlue, Underline))
assert.Equal(t, "\x1b[34;1m\x1b[4m\x1b[36;1ma\x1b[0m\x1b[34;1mbc\x1b[0m", HighlightSingleRune("abc", 0, BrightBlue, Underline+BrightCyan))
assert.Equal(t, "\x1b[34;1ma\x1b[4m\x1b[36;1mb\x1b[0m\x1b[34;1mc\x1b[0m", HighlightSingleRune("abc", 1, BrightBlue, Underline+BrightCyan))
Expand All @@ -166,6 +172,16 @@ func TestHighlightSingleRune(t *testing.T) {
Enabled = true
}

// BenchmarkSingleRune-4 11593182 96.75 ns/op 0 B/op 0 allocs/op
func BenchmarkSingleRune(b *testing.B) {
buf := &bytes.Buffer{}

for range b.N {
WriteHighlightSingleRune(buf, "cantalope", 1, Red, Green)
buf.Reset()
}
}

func TestStringLength(t *testing.T) {
assert.Equal(t, 4, StrLen("test"))
assert.Equal(t, 4, StrLen(Wrap(Red, "test")))
Expand Down
9 changes: 5 additions & 4 deletions pkg/multiterm/termrenderers/heatmap.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package termrenderers

import (
"io"
"rare/pkg/aggregation"
"rare/pkg/aggregation/sorting"
"rare/pkg/color"
Expand Down Expand Up @@ -129,11 +130,11 @@ func (s *Heatmap) WriteHeader(colNames ...string) (colCount int) {
writeRepeat(&sb, delim, indent)
i += indent
}
sb.WriteString(underlineHeaderChar(name, colCount-i-1))
underlineHeaderChar(&sb, name, colCount-i-1)
break
}

sb.WriteString(underlineHeaderChar(name, 0))
underlineHeaderChar(&sb, name, 0)
i += nameLen
}

Expand Down Expand Up @@ -180,6 +181,6 @@ func writeRepeat(sb *strings.Builder, r rune, count int) {
}
}

func underlineHeaderChar(word string, letter int) string {
return color.HighlightSingleRune(word, letter, color.BrightBlue, color.Underline+color.BrightCyan)
func underlineHeaderChar(w io.StringWriter, word string, letter int) {
color.WriteHighlightSingleRune(w, word, letter, color.BrightBlue, color.Underline+color.BrightCyan)
}
Loading