mirror of
https://github.com/walles/moar.git
synced 2024-11-22 03:14:56 +03:00
Introduce colorType to ansiString
This commit is contained in:
parent
44136f6524
commit
f26ae4ff9a
@ -10,6 +10,7 @@ import (
|
||||
// Create using NewColor16(), NewColor256 or NewColor24Bit(), or use
|
||||
// ColorDefault.
|
||||
type Color uint32
|
||||
|
||||
type ColorCount uint8
|
||||
|
||||
const (
|
||||
@ -32,6 +33,14 @@ const (
|
||||
ColorCount24bit
|
||||
)
|
||||
|
||||
type colorType uint8
|
||||
|
||||
const (
|
||||
colorTypeForeground colorType = iota
|
||||
colorTypeBackground
|
||||
colorTypeUnderline
|
||||
)
|
||||
|
||||
// Reset to default foreground / background color
|
||||
var ColorDefault = newColor(ColorCountDefault, 0)
|
||||
|
||||
@ -88,35 +97,50 @@ func (color Color) colorValue() uint32 {
|
||||
// Render color into an ANSI string.
|
||||
//
|
||||
// Ref: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
|
||||
func (color Color) ansiString(foreground bool, terminalColorCount ColorCount) string {
|
||||
fgBgMarker := "3"
|
||||
if !foreground {
|
||||
fgBgMarker = "4"
|
||||
func (color Color) ansiString(cType colorType, terminalColorCount ColorCount) string {
|
||||
var typeMarker string
|
||||
if cType == colorTypeForeground {
|
||||
typeMarker = "3"
|
||||
} else if cType == colorTypeBackground {
|
||||
typeMarker = "4"
|
||||
} else if cType == colorTypeUnderline {
|
||||
typeMarker = "5"
|
||||
} else {
|
||||
panic(fmt.Errorf("unhandled color type %d", cType))
|
||||
}
|
||||
|
||||
if color.ColorCount() == ColorCountDefault {
|
||||
return fmt.Sprint("\x1b[", fgBgMarker, "9m")
|
||||
return fmt.Sprint("\x1b[", typeMarker, "9m")
|
||||
}
|
||||
|
||||
color = color.downsampleTo(terminalColorCount)
|
||||
|
||||
// We never create any ColorCount8 colors, but we store them as
|
||||
// ColorCount16. So this if() statement will cover both.
|
||||
if color.ColorCount() == ColorCount16 {
|
||||
if cType == colorTypeUnderline {
|
||||
// Only 256 and 24 bit colors supported for underline color
|
||||
return ""
|
||||
}
|
||||
|
||||
value := color.colorValue()
|
||||
if value < 8 {
|
||||
return fmt.Sprint("\x1b[", fgBgMarker, value, "m")
|
||||
return fmt.Sprint("\x1b[", typeMarker, value, "m")
|
||||
} else if value <= 15 {
|
||||
fgBgMarker := "9"
|
||||
if !foreground {
|
||||
fgBgMarker = "10"
|
||||
typeMarker := "9"
|
||||
if cType == colorTypeBackground {
|
||||
typeMarker = "10"
|
||||
}
|
||||
return fmt.Sprint("\x1b[", fgBgMarker, value-8, "m")
|
||||
return fmt.Sprint("\x1b[", typeMarker, value-8, "m")
|
||||
}
|
||||
|
||||
panic(fmt.Errorf("unhandled color16 value %d", value))
|
||||
}
|
||||
|
||||
if color.ColorCount() == ColorCount256 {
|
||||
value := color.colorValue()
|
||||
if value <= 255 {
|
||||
return fmt.Sprint("\x1b[", fgBgMarker, "8;5;", value, "m")
|
||||
return fmt.Sprint("\x1b[", typeMarker, "8;5;", value, "m")
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,7 +150,7 @@ func (color Color) ansiString(foreground bool, terminalColorCount ColorCount) st
|
||||
green := (value & 0xff00) >> 8
|
||||
blue := value & 0xff
|
||||
|
||||
return fmt.Sprint("\x1b[", fgBgMarker, "8;2;", red, ";", green, ";", blue, "m")
|
||||
return fmt.Sprint("\x1b[", typeMarker, "8;2;", red, ";", green, ";", blue, "m")
|
||||
}
|
||||
|
||||
panic(fmt.Errorf("unhandled color type=%d %s", color.ColorCount(), color.String()))
|
||||
@ -134,12 +158,12 @@ func (color Color) ansiString(foreground bool, terminalColorCount ColorCount) st
|
||||
|
||||
func (color Color) ForegroundAnsiString(terminalColorCount ColorCount) string {
|
||||
// FIXME: Test this function with all different color types.
|
||||
return color.ansiString(true, terminalColorCount)
|
||||
return color.ansiString(colorTypeForeground, terminalColorCount)
|
||||
}
|
||||
|
||||
func (color Color) BackgroundAnsiString(terminalColorCount ColorCount) string {
|
||||
// FIXME: Test this function with all different color types.
|
||||
return color.ansiString(false, terminalColorCount)
|
||||
return color.ansiString(colorTypeBackground, terminalColorCount)
|
||||
}
|
||||
|
||||
func (color Color) String() string {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package twin
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
@ -30,16 +31,22 @@ func TestRealWorldDownsampling(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAnsiStringWithDownSampling(t *testing.T) {
|
||||
actual := NewColor24Bit(0xd0, 0xd0, 0xd0).ansiString(colorTypeForeground, ColorCount256)
|
||||
actual = strings.ReplaceAll(actual, "\x1b", "ESC")
|
||||
expected := "ESC[38;5;252m"
|
||||
assert.Equal(t,
|
||||
NewColor24Bit(0xd0, 0xd0, 0xd0).ansiString(true, ColorCount256),
|
||||
"\x1b[38;5;252m",
|
||||
actual,
|
||||
expected,
|
||||
)
|
||||
}
|
||||
|
||||
func TestAnsiStringDefault(t *testing.T) {
|
||||
actual := ColorDefault.ansiString(colorTypeBackground, ColorCount16)
|
||||
actual = strings.ReplaceAll(actual, "\x1b", "ESC")
|
||||
expected := "ESC[49m"
|
||||
assert.Equal(t,
|
||||
ColorDefault.ansiString(true, ColorCount16),
|
||||
"\x1b[39m",
|
||||
actual,
|
||||
expected,
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user