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
2 changes: 1 addition & 1 deletion internal/tableprinter/table_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func NewWithWriter(w io.Writer, isTTY bool, maxWidth int, cs *iostreams.ColorSch
tp.AddHeader(
upperCasedHeaders,
WithPadding(paddingFunc),
WithColor(cs.LightGrayUnderline),
WithColor(cs.TableHeader),
)
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/gist/list/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ func Test_listRun(t *testing.T) {
)
},
wantOut: heredoc.Docf(`
%[1]s[0;2;4;37mID %[1]s[0m %[1]s[0;2;4;37mDESCRIPTION %[1]s[0m %[1]s[0;2;4;37mFILES %[1]s[0m %[1]s[0;2;4;37mVISIBILITY%[1]s[0m %[1]s[0;2;4;37mUPDATED %[1]s[0m
%[1]s[0;4;39mID %[1]s[0m %[1]s[0;4;39mDESCRIPTION %[1]s[0m %[1]s[0;4;39mFILES %[1]s[0m %[1]s[0;4;39mVISIBILITY%[1]s[0m %[1]s[0;4;39mUPDATED %[1]s[0m
1234 %[1]s[0;30;43mocto%[1]s[0m%[1]s[0;1;39m match in the description%[1]s[0m 1 file %[1]s[0;32mpublic %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[m
2345 %[1]s[0;1;39mmatch in the file name %[1]s[0m %[1]s[0;30;43m2 files%[1]s[0m %[1]s[0;31msecret %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[m
`, "\x1b"),
Expand Down Expand Up @@ -694,7 +694,7 @@ func Test_highlightMatch(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cs := iostreams.NewColorScheme(tt.color, false, false)
cs := iostreams.NewColorScheme(tt.color, false, false, iostreams.NoTheme)

matched := false
got, err := highlightMatch(tt.input, regex, &matched, cs.Blue, cs.Highlight)
Expand Down
63 changes: 42 additions & 21 deletions pkg/iostreams/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,53 @@ import (
)

const (
NoTheme = "none"
DarkTheme = "dark"
LightTheme = "light"
highlightStyle = "black:yellow"
)

// Special cases like darkThemeTableHeader / lightThemeTableHeader are necessary when using color and modifiers
// (bold, underline, dim) because ansi.ColorFunc requires a foreground color and resets formats.
var (
magenta = ansi.ColorFunc("magenta")
cyan = ansi.ColorFunc("cyan")
red = ansi.ColorFunc("red")
yellow = ansi.ColorFunc("yellow")
blue = ansi.ColorFunc("blue")
green = ansi.ColorFunc("green")
gray = ansi.ColorFunc("black+h")
lightGrayUnderline = ansi.ColorFunc("white+du")
bold = ansi.ColorFunc("default+b")
cyanBold = ansi.ColorFunc("cyan+b")
greenBold = ansi.ColorFunc("green+b")
highlightStart = ansi.ColorCode(highlightStyle)
highlight = ansi.ColorFunc(highlightStyle)
magenta = ansi.ColorFunc("magenta")
cyan = ansi.ColorFunc("cyan")
red = ansi.ColorFunc("red")
yellow = ansi.ColorFunc("yellow")
blue = ansi.ColorFunc("blue")
green = ansi.ColorFunc("green")
gray = ansi.ColorFunc("black+h")
bold = ansi.ColorFunc("default+b")
cyanBold = ansi.ColorFunc("cyan+b")
greenBold = ansi.ColorFunc("green+b")
highlightStart = ansi.ColorCode(highlightStyle)
highlight = ansi.ColorFunc(highlightStyle)
darkThemeTableHeader = ansi.ColorFunc("white+du")
lightThemeTableHeader = ansi.ColorFunc("black+hu")
noThemeTableHeader = ansi.ColorFunc("default+u")

gray256 = func(t string) string {
return fmt.Sprintf("\x1b[%d;5;%dm%s\x1b[m", 38, 242, t)
}
)

func NewColorScheme(enabled, is256enabled bool, trueColor bool) *ColorScheme {
// NewColorScheme initializes color logic based on provided terminal capabilities.
// Logic dealing with terminal theme detected, such as whether color is enabled, 8-bit color supported, true color supported,
// and terminal theme detected.
func NewColorScheme(enabled, is256enabled, trueColor bool, theme string) *ColorScheme {
return &ColorScheme{
enabled: enabled,
is256enabled: is256enabled,
hasTrueColor: trueColor,
theme: theme,
}
}

type ColorScheme struct {
enabled bool
is256enabled bool
hasTrueColor bool
theme string
}

func (c *ColorScheme) Enabled() bool {
Expand Down Expand Up @@ -115,13 +127,6 @@ func (c *ColorScheme) Grayf(t string, args ...interface{}) string {
return c.Gray(fmt.Sprintf(t, args...))
}

func (c *ColorScheme) LightGrayUnderline(t string) string {
if !c.enabled {
return t
}
return lightGrayUnderline(t)
}

func (c *ColorScheme) Magenta(t string) string {
if !c.enabled {
return t
Expand Down Expand Up @@ -254,3 +259,19 @@ func (c *ColorScheme) HexToRGB(hex string, x string) string {
b, _ := strconv.ParseInt(hex[4:6], 16, 64)
return fmt.Sprintf("\033[38;2;%d;%d;%dm%s\033[0m", r, g, b, x)
}

func (c *ColorScheme) TableHeader(t string) string {
// Table headers are only stylized if color is enabled including underline modifier.
if !c.enabled {
return t
}

switch c.theme {
case DarkTheme:
return darkThemeTableHeader(t)
case LightTheme:
return lightThemeTableHeader(t)
default:
return noThemeTableHeader(t)
}
}
98 changes: 90 additions & 8 deletions pkg/iostreams/color_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package iostreams

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -19,28 +20,28 @@ func TestColorFromRGB(t *testing.T) {
hex: "fc0303",
text: "red",
wants: "\033[38;2;252;3;3mred\033[0m",
cs: NewColorScheme(true, true, true),
cs: NewColorScheme(true, true, true, NoTheme),
},
{
name: "no truecolor",
hex: "fc0303",
text: "red",
wants: "red",
cs: NewColorScheme(true, true, false),
cs: NewColorScheme(true, true, false, NoTheme),
},
{
name: "no color",
hex: "fc0303",
text: "red",
wants: "red",
cs: NewColorScheme(false, false, false),
cs: NewColorScheme(false, false, false, NoTheme),
},
{
name: "invalid hex",
hex: "fc0",
text: "red",
wants: "red",
cs: NewColorScheme(false, false, false),
cs: NewColorScheme(false, false, false, NoTheme),
},
}

Expand All @@ -63,28 +64,28 @@ func TestHexToRGB(t *testing.T) {
hex: "fc0303",
text: "red",
wants: "\033[38;2;252;3;3mred\033[0m",
cs: NewColorScheme(true, true, true),
cs: NewColorScheme(true, true, true, NoTheme),
},
{
name: "no truecolor",
hex: "fc0303",
text: "red",
wants: "red",
cs: NewColorScheme(true, true, false),
cs: NewColorScheme(true, true, false, NoTheme),
},
{
name: "no color",
hex: "fc0303",
text: "red",
wants: "red",
cs: NewColorScheme(false, false, false),
cs: NewColorScheme(false, false, false, NoTheme),
},
{
name: "invalid hex",
hex: "fc0",
text: "red",
wants: "red",
cs: NewColorScheme(false, false, false),
cs: NewColorScheme(false, false, false, NoTheme),
},
}

Expand All @@ -93,3 +94,84 @@ func TestHexToRGB(t *testing.T) {
assert.Equal(t, tt.wants, output)
}
}

func TestTableHeader(t *testing.T) {
reset := "\x1b[0m"
defaultUnderline := "\x1b[0;4;39m"
brightBlackUnderline := "\x1b[0;4;90m"
dimBlackUnderline := "\x1b[0;2;4;37m"

tests := []struct {
name string
cs *ColorScheme
input string
expected string
}{
{
name: "when color is disabled, text is not stylized",
cs: NewColorScheme(false, false, false, NoTheme),
input: "this should not be stylized",
expected: "this should not be stylized",
},
{
name: "when 4-bit color is enabled but no theme, 4-bit default color and underline are used",
cs: NewColorScheme(true, false, false, NoTheme),
input: "this should have no explicit color but underlined",
expected: fmt.Sprintf("%sthis should have no explicit color but underlined%s", defaultUnderline, reset),
},
{
name: "when 4-bit color is enabled and theme is light, 4-bit dark color and underline are used",
cs: NewColorScheme(true, false, false, LightTheme),
input: "this should have dark foreground color and underlined",
expected: fmt.Sprintf("%sthis should have dark foreground color and underlined%s", brightBlackUnderline, reset),
},
{
name: "when 4-bit color is enabled and theme is dark, 4-bit light color and underline are used",
cs: NewColorScheme(true, false, false, DarkTheme),
input: "this should have light foreground color and underlined",
expected: fmt.Sprintf("%sthis should have light foreground color and underlined%s", dimBlackUnderline, reset),
},
{
name: "when 8-bit color is enabled but no theme, 4-bit default color and underline are used",
cs: NewColorScheme(true, true, false, NoTheme),
input: "this should have no explicit color but underlined",
expected: fmt.Sprintf("%sthis should have no explicit color but underlined%s", defaultUnderline, reset),
},
{
name: "when 8-bit color is enabled and theme is light, 4-bit dark color and underline are used",
cs: NewColorScheme(true, true, false, LightTheme),
input: "this should have dark foreground color and underlined",
expected: fmt.Sprintf("%sthis should have dark foreground color and underlined%s", brightBlackUnderline, reset),
},
{
name: "when 8-bit color is true and theme is dark, 4-bit light color and underline are used",
cs: NewColorScheme(true, true, false, DarkTheme),
input: "this should have light foreground color and underlined",
expected: fmt.Sprintf("%sthis should have light foreground color and underlined%s", dimBlackUnderline, reset),
},
{
name: "when 24-bit color is enabled but no theme, 4-bit default color and underline are used",
cs: NewColorScheme(true, true, true, NoTheme),
input: "this should have no explicit color but underlined",
expected: fmt.Sprintf("%sthis should have no explicit color but underlined%s", defaultUnderline, reset),
},
{
name: "when 24-bit color is enabled and theme is light, 4-bit dark color and underline are used",
cs: NewColorScheme(true, true, true, LightTheme),
input: "this should have dark foreground color and underlined",
expected: fmt.Sprintf("%sthis should have dark foreground color and underlined%s", brightBlackUnderline, reset),
},
{
name: "when 24-bit color is true and theme is dark, 4-bit light color and underline are used",
cs: NewColorScheme(true, true, true, DarkTheme),
input: "this should have light foreground color and underlined",
expected: fmt.Sprintf("%sthis should have light foreground color and underlined%s", dimBlackUnderline, reset),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, tt.cs.TableHeader(tt.input))
})
}
}
2 changes: 1 addition & 1 deletion pkg/iostreams/iostreams.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ func (s *IOStreams) TerminalWidth() int {
}

func (s *IOStreams) ColorScheme() *ColorScheme {
return NewColorScheme(s.ColorEnabled(), s.ColorSupport256(), s.HasTrueColor())
return NewColorScheme(s.ColorEnabled(), s.ColorSupport256(), s.HasTrueColor(), s.TerminalTheme())
}

func (s *IOStreams) ReadUserFile(fn string) ([]byte, error) {
Expand Down
Loading