Skip to content

Commit

Permalink
Introduce “basic” colour theme
Browse files Browse the repository at this point in the history
Resolves #325.

This PR introduces a new `basic` colour theme, which is based on 8-bit
ANSI colours. It doesn’t override the default text colour, so the colour
of black/white text is “responsive” automatically.
  • Loading branch information
jotaen authored Aug 17, 2024
1 parent 474d5df commit 798c082
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 35 deletions.
6 changes: 3 additions & 3 deletions klog/app/cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ func (opt *Config) Run(ctx app.Context) app.Error {
opt.NoStyleArgs.Apply(&ctx)
styler, _ := ctx.Serialise()
for i, e := range app.CONFIG_FILE_ENTRIES {
ctx.Print(styler.Props(tf.StyleProps{Color: tf.SUBDUED}).Format(util.Reflower.Reflow(e.Help.Summary, []string{"# "})))
ctx.Print(styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED}).Format(util.Reflower.Reflow(e.Help.Summary, []string{"# "})))
ctx.Print("\n")
ctx.Print(styler.Props(tf.StyleProps{Color: tf.SUBDUED}).Format(util.Reflower.Reflow("Value: "+e.Help.Value, []string{"# - ", "# "})))
ctx.Print(styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED}).Format(util.Reflower.Reflow("Value: "+e.Help.Value, []string{"# - ", "# "})))
ctx.Print("\n")
ctx.Print(styler.Props(tf.StyleProps{Color: tf.SUBDUED}).Format(util.Reflower.Reflow("Default: "+e.Help.Default, []string{"# - ", "# "})))
ctx.Print(styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED}).Format(util.Reflower.Reflow("Default: "+e.Help.Default, []string{"# - ", "# "})))
ctx.Print("\n")
ctx.Print(styler.Props(tf.StyleProps{Color: tf.RED}).Format(e.Name))
ctx.Print(" = ")
Expand Down
2 changes: 1 addition & 1 deletion klog/app/cli/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func printWithDurations(styler tf.Styler, ls parser.Lines) string {
length := len(p.d.ToString())
value := ""
if p.isSub {
value += styler.Props(tf.StyleProps{Color: tf.SUBDUED}).Format(p.d.ToString())
value += styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED}).Format(p.d.ToString())
} else {
value += styler.Props(tf.StyleProps{IsUnderlined: true}).Format(p.d.ToString())
}
Expand Down
4 changes: 2 additions & 2 deletions klog/app/cli/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (opt *Tags) Run(ctx app.Context) app.Error {
table := tf.NewTable(numberOfColumns, " ")
for _, t := range totalByTag {
totalString := serialiser.Duration(t.Total)
countString := styler.Props(tf.StyleProps{Color: tf.SUBDUED}).Format(fmt.Sprintf(" (%d)", t.Count))
countString := styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED}).Format(fmt.Sprintf(" (%d)", t.Count))
if t.Tag.Value() == "" {
table.CellL("#" + t.Tag.Name())
table.CellL(totalString)
Expand All @@ -71,7 +71,7 @@ func (opt *Tags) Run(ctx app.Context) app.Error {
table.CellL(countString)
}
} else if opt.Values {
table.CellL(" " + styler.Props(tf.StyleProps{Color: tf.SUBDUED}).Format(t.Tag.Value()))
table.CellL(" " + styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED}).Format(t.Tag.Value()))
table.Skip(1)
table.CellL(totalString)
if opt.Count {
Expand Down
67 changes: 47 additions & 20 deletions klog/app/cli/terminalformat/colour_theme.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,21 @@
package terminalformat

type ColourTheme string
type colourCodes map[Colour]string

const (
COLOUR_THEME_NO_COLOUR = ColourTheme("no_colour")
COLOUR_THEME_DARK = ColourTheme("dark")
COLOUR_THEME_LIGHT = ColourTheme("light")
COLOUR_THEME_BASIC = ColourTheme("basic")
)

func NewStyler(c ColourTheme) Styler {
baseColouredStyler := Styler{
props: StyleProps{},
colourCodes: make(map[Colour]string),
reset: "\033[0m",
foregroundPrefix: "\033[38;5;",
backgroundPrefix: "\033[48;5;",
colourSuffix: "m",
underlined: "\033[4m",
bold: "\033[1m",
}

switch c {
case COLOUR_THEME_NO_COLOUR:
return Styler{
props: StyleProps{},
colourCodes: make(map[Colour]string),
colourCodes: make(colourCodes),
reset: "",
foregroundPrefix: "",
backgroundPrefix: "",
Expand All @@ -33,31 +24,67 @@ func NewStyler(c ColourTheme) Styler {
bold: "",
}
case COLOUR_THEME_DARK:
baseColouredStyler.colourCodes = map[Colour]string{
return newStyler256bit(colourCodes{
TEXT: "015",
TEXT_SUBDUED: "249",
TEXT_INVERSE: "000",
GREEN: "120",
RED: "167",
BLUE_DARK: "117",
BLUE_LIGHT: "027",
SUBDUED: "249",
PURPLE: "213",
YELLOW: "221",
}
return baseColouredStyler
})
case COLOUR_THEME_LIGHT:
baseColouredStyler.colourCodes = map[Colour]string{
return newStyler256bit(colourCodes{
TEXT: "000",
TEXT_SUBDUED: "237",
TEXT_INVERSE: "015",
GREEN: "028",
RED: "124",
BLUE_DARK: "025",
BLUE_LIGHT: "033",
SUBDUED: "237",
PURPLE: "055",
YELLOW: "208",
}
return baseColouredStyler
})
case COLOUR_THEME_BASIC:
return newStyler8bit(colourCodes{
TEXT: "", // Disabled
TEXT_SUBDUED: "", // Disabled
TEXT_INVERSE: "0",
GREEN: "2",
RED: "1",
BLUE_DARK: "4",
BLUE_LIGHT: "6",
PURPLE: "5",
YELLOW: "3",
})
}
panic("Unknown colour theme")
}

func newStyler256bit(cc colourCodes) Styler {
return Styler{
props: StyleProps{},
colourCodes: cc,
reset: "\033[0m",
foregroundPrefix: "\033[38;5;",
backgroundPrefix: "\033[48;5;",
colourSuffix: "m",
underlined: "\033[4m",
bold: "\033[1m",
}
}

func newStyler8bit(cc colourCodes) Styler {
return Styler{
props: StyleProps{},
colourCodes: cc,
reset: "\033[0m",
foregroundPrefix: "\033[3",
backgroundPrefix: "\033[4",
colourSuffix: "m",
underlined: "\033[4m",
bold: "\033[1m",
}
}
6 changes: 3 additions & 3 deletions klog/app/cli/terminalformat/style.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ type Colour int
const (
unspecified = iota
TEXT
TEXT_SUBDUED
TEXT_INVERSE
GREEN
RED
YELLOW
BLUE_DARK
BLUE_LIGHT
SUBDUED
PURPLE
)

Expand All @@ -50,11 +50,11 @@ func (s Styler) FormatAndRestore(text string, previousStyle Styler) string {
func (s Styler) seqs() string {
seqs := s.reset

if s.props.Color != unspecified {
if s.props.Color != unspecified && s.colourCodes[s.props.Color] != "" {
seqs = seqs + s.foregroundPrefix + s.colourCodes[s.props.Color] + s.colourSuffix
}

if s.props.Background != unspecified {
if s.props.Background != unspecified && s.colourCodes[s.props.Background] != "" {
seqs = seqs + s.backgroundPrefix + s.colourCodes[s.props.Background] + s.colourSuffix
}

Expand Down
4 changes: 2 additions & 2 deletions klog/app/cli/today.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func handle(opt *Today, ctx app.Context) app.Error {
table.CellR(serialiser.Time(currentEndTime))
} else {
table.CellR(
styler.Props(tf.StyleProps{Color: tf.SUBDUED}).
styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED}).
Format("(" + currentEndTime.ToString() + ")"))
}
} else {
Expand Down Expand Up @@ -177,7 +177,7 @@ func handle(opt *Today, ctx app.Context) app.Error {
table.CellR(serialiser.Time(grandEndTime))
} else {
table.CellR(
styler.Props(tf.StyleProps{Color: tf.SUBDUED}).
styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED}).
Format("(" + grandEndTime.ToString() + ")"))
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion klog/app/cli/util/prettifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func PrettifyParsingError(err app.ParserErrors, styler tf.Styler) error {
}
message += "\n"
message += fmt.Sprintf(
styler.Props(tf.StyleProps{Color: tf.SUBDUED}).Format(INDENT+"%s"),
styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED}).Format(INDENT+"%s"),
// Replace all tabs with one space each, otherwise the carets might
// not be in line with the text anymore (since we can’t know how wide
// a tab is).
Expand Down
4 changes: 3 additions & 1 deletion klog/app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ var CONFIG_FILE_ENTRIES = []ConfigFileEntries[any]{
config.ColourScheme.override(tf.COLOUR_THEME_NO_COLOUR, configOriginFile)
case string(tf.COLOUR_THEME_LIGHT):
config.ColourScheme.override(tf.COLOUR_THEME_LIGHT, configOriginFile)
case string(tf.COLOUR_THEME_BASIC):
config.ColourScheme.override(tf.COLOUR_THEME_BASIC, configOriginFile)
default:
return errors.New("The value must be `dark`, `light` or `no_colour`")
}
Expand All @@ -214,7 +216,7 @@ var CONFIG_FILE_ENTRIES = []ConfigFileEntries[any]{
},
Help: Help{
Summary: "The colour scheme of your terminal, so that klog can choose an optimal colour theme for its output.",
Value: "The config property must be one of: `dark`, `light` or `no_colour`",
Value: "The config property must be one of: `dark`, `light`, `basic`, or `no_colour`",
Default: "If absent/empty, klog assumes a `dark` theme.",
},
}, {
Expand Down
1 change: 1 addition & 0 deletions klog/app/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func TestSetsColourSchemeParamFromConfigFile(t *testing.T) {
}{
{`colour_scheme = dark`, tf.COLOUR_THEME_DARK},
{`colour_scheme = light`, tf.COLOUR_THEME_LIGHT},
{`colour_scheme = basic`, tf.COLOUR_THEME_BASIC},
{`colour_scheme = no_colour`, tf.COLOUR_THEME_NO_COLOUR},
} {
c, _ := NewConfig(
Expand Down
4 changes: 2 additions & 2 deletions klog/app/text_serialiser.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ func (cs TextSerialiser) ShouldTotal(d klog.Duration) string {

func (cs TextSerialiser) Summary(s parser.SummaryText) string {
txt := s.ToString()
summaryStyler := cs.Styler.Props(tf.StyleProps{Color: tf.SUBDUED})
summaryStyler := cs.Styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED})
txt = klog.HashTagPattern.ReplaceAllStringFunc(txt, func(h string) string {
return cs.Styler.Props(tf.StyleProps{Color: tf.SUBDUED, IsBold: true}).FormatAndRestore(
return cs.Styler.Props(tf.StyleProps{Color: tf.TEXT_SUBDUED, IsBold: true}).FormatAndRestore(
h, summaryStyler,
)
})
Expand Down

0 comments on commit 798c082

Please sign in to comment.