Skip to content

Commit bdde01c

Browse files
authored
Merge pull request #2 from injeniero/main
Add support for Themes
2 parents e094ac7 + a125e81 commit bdde01c

File tree

5 files changed

+374
-81
lines changed

5 files changed

+374
-81
lines changed

colors.go

Lines changed: 0 additions & 19 deletions
This file was deleted.

encoding.go

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,91 +9,98 @@ import (
99
)
1010

1111
type encoder struct {
12-
noColor bool
13-
timeFormat string
12+
opts HandlerOptions
1413
}
1514

16-
func (e *encoder) NewLine(buf *buffer) {
15+
func (e encoder) NewLine(buf *buffer) {
1716
buf.AppendByte('\n')
1817
}
1918

20-
func (e *encoder) withColor(b *buffer, c color, f func()) {
21-
if c == "" || e.noColor {
19+
func (e encoder) withColor(b *buffer, c ANSIMod, f func()) {
20+
if c == "" || e.opts.NoColor {
2221
f()
2322
return
2423
}
2524
b.AppendString(string(c))
2625
f()
27-
b.AppendString(string(reset))
26+
b.AppendString(string(ResetMod))
2827
}
2928

30-
func (e *encoder) writeColoredTime(w *buffer, t time.Time, format string, seq color) {
31-
e.withColor(w, seq, func() {
29+
func (e encoder) writeColoredTime(w *buffer, t time.Time, format string, c ANSIMod) {
30+
e.withColor(w, c, func() {
3231
w.AppendTime(t, format)
3332
})
3433
}
3534

36-
func (e *encoder) writeColoredString(w *buffer, s string, seq color) {
37-
e.withColor(w, seq, func() {
35+
func (e encoder) writeColoredString(w *buffer, s string, c ANSIMod) {
36+
e.withColor(w, c, func() {
3837
w.AppendString(s)
3938
})
4039
}
4140

42-
func (e *encoder) writeColoredInt(w *buffer, i int64, seq color) {
43-
e.withColor(w, seq, func() {
41+
func (e encoder) writeColoredInt(w *buffer, i int64, c ANSIMod) {
42+
e.withColor(w, c, func() {
4443
w.AppendInt(i)
4544
})
4645
}
4746

48-
func (e *encoder) writeColoredUint(w *buffer, i uint64, seq color) {
49-
e.withColor(w, seq, func() {
47+
func (e encoder) writeColoredUint(w *buffer, i uint64, c ANSIMod) {
48+
e.withColor(w, c, func() {
5049
w.AppendUint(i)
5150
})
5251
}
5352

54-
func (e *encoder) writeColoredFloat(w *buffer, i float64, seq color) {
55-
e.withColor(w, seq, func() {
53+
func (e encoder) writeColoredFloat(w *buffer, i float64, c ANSIMod) {
54+
e.withColor(w, c, func() {
5655
w.AppendFloat(i)
5756
})
5857
}
5958

60-
func (e *encoder) writeColoredBool(w *buffer, b bool, seq color) {
61-
e.withColor(w, seq, func() {
59+
func (e encoder) writeColoredBool(w *buffer, b bool, c ANSIMod) {
60+
e.withColor(w, c, func() {
6261
w.AppendBool(b)
6362
})
6463
}
6564

66-
func (e *encoder) writeColoredDuration(w *buffer, d time.Duration, seq color) {
67-
e.withColor(w, seq, func() {
65+
func (e encoder) writeColoredDuration(w *buffer, d time.Duration, c ANSIMod) {
66+
e.withColor(w, c, func() {
6867
w.AppendDuration(d)
6968
})
7069
}
7170

72-
func (e *encoder) writeTimestamp(buf *buffer, tt time.Time) {
73-
e.writeColoredTime(buf, tt, e.timeFormat, colorTimestamp)
71+
func (e encoder) writeTimestamp(buf *buffer, tt time.Time) {
72+
e.writeColoredTime(buf, tt, e.opts.TimeFormat, e.opts.Theme.Timestamp())
7473
buf.AppendByte(' ')
7574
}
7675

77-
func (e *encoder) writeSource(buf *buffer, pc uintptr, cwd string) {
76+
func (e encoder) writeSource(buf *buffer, pc uintptr, cwd string) {
7877
frame, _ := runtime.CallersFrames([]uintptr{pc}).Next()
7978
if cwd != "" {
8079
if ff, err := filepath.Rel(cwd, frame.File); err == nil {
8180
frame.File = ff
8281
}
8382
}
84-
e.withColor(buf, colorSource, func() {
83+
e.withColor(buf, e.opts.Theme.Source(), func() {
8584
buf.AppendString(frame.File)
8685
buf.AppendByte(':')
8786
buf.AppendInt(int64(frame.Line))
8887
})
89-
e.writeColoredString(buf, " > ", colorAttrKey)
88+
e.writeColoredString(buf, " > ", e.opts.Theme.AttrKey())
9089
}
9190

92-
func (e *encoder) writeMessage(buf *buffer, msg string) {
93-
e.writeColoredString(buf, msg, colorMessage)
91+
func (e encoder) writeMessage(buf *buffer, level slog.Level, msg string) {
92+
if level >= slog.LevelInfo {
93+
e.writeColoredString(buf, msg, e.opts.Theme.Message())
94+
} else {
95+
e.writeColoredString(buf, msg, e.opts.Theme.MessageDebug())
96+
}
9497
}
9598

96-
func (e *encoder) writeAttr(buf *buffer, a slog.Attr, group string) {
99+
func (e encoder) writeAttr(buf *buffer, a slog.Attr, group string) {
100+
// Elide empty Attrs.
101+
if a.Equal(slog.Attr{}) {
102+
return
103+
}
97104
value := a.Value.Resolve()
98105
if value.Kind() == slog.KindGroup {
99106
subgroup := a.Key
@@ -106,7 +113,7 @@ func (e *encoder) writeAttr(buf *buffer, a slog.Attr, group string) {
106113
return
107114
}
108115
buf.AppendByte(' ')
109-
e.withColor(buf, colorAttrKey, func() {
116+
e.withColor(buf, e.opts.Theme.AttrKey(), func() {
110117
if group != "" {
111118
buf.AppendString(group)
112119
buf.AppendByte('.')
@@ -117,60 +124,61 @@ func (e *encoder) writeAttr(buf *buffer, a slog.Attr, group string) {
117124
e.writeValue(buf, value)
118125
}
119126

120-
func (e *encoder) writeValue(buf *buffer, value slog.Value) {
127+
func (e encoder) writeValue(buf *buffer, value slog.Value) {
128+
attrValue := e.opts.Theme.AttrValue()
121129
switch value.Kind() {
122130
case slog.KindInt64:
123-
e.writeColoredInt(buf, value.Int64(), colorAttrValue)
131+
e.writeColoredInt(buf, value.Int64(), attrValue)
124132
case slog.KindBool:
125-
e.writeColoredBool(buf, value.Bool(), colorAttrValue)
133+
e.writeColoredBool(buf, value.Bool(), attrValue)
126134
case slog.KindFloat64:
127-
e.writeColoredFloat(buf, value.Float64(), colorAttrValue)
135+
e.writeColoredFloat(buf, value.Float64(), attrValue)
128136
case slog.KindTime:
129-
e.writeColoredTime(buf, value.Time(), e.timeFormat, colorAttrValue)
137+
e.writeColoredTime(buf, value.Time(), e.opts.TimeFormat, attrValue)
130138
case slog.KindUint64:
131-
e.writeColoredUint(buf, value.Uint64(), colorAttrValue)
139+
e.writeColoredUint(buf, value.Uint64(), attrValue)
132140
case slog.KindDuration:
133-
e.writeColoredDuration(buf, value.Duration(), colorAttrValue)
141+
e.writeColoredDuration(buf, value.Duration(), attrValue)
134142
case slog.KindAny:
135143
switch v := value.Any().(type) {
136144
case error:
137-
e.writeColoredString(buf, v.Error(), colorErrorValue)
145+
e.writeColoredString(buf, v.Error(), e.opts.Theme.AttrValueError())
138146
return
139147
case fmt.Stringer:
140-
e.writeColoredString(buf, v.String(), colorAttrValue)
148+
e.writeColoredString(buf, v.String(), attrValue)
141149
return
142150
}
143151
fallthrough
144152
case slog.KindString:
145153
fallthrough
146154
default:
147-
e.writeColoredString(buf, value.String(), colorAttrValue)
155+
e.writeColoredString(buf, value.String(), attrValue)
148156
}
149157
}
150158

151-
func (e *encoder) writeLevel(buf *buffer, l slog.Level) {
152-
var style color
159+
func (e encoder) writeLevel(buf *buffer, l slog.Level) {
160+
var style ANSIMod
153161
var str string
154162
var delta int
155163
switch {
156164
case l >= slog.LevelError:
157-
style = colorLevelError
165+
style = e.opts.Theme.LevelError()
158166
str = "ERR"
159167
delta = int(l - slog.LevelError)
160168
case l >= slog.LevelWarn:
161-
style = colorLevelWarn
169+
style = e.opts.Theme.LevelWarn()
162170
str = "WRN"
163171
delta = int(l - slog.LevelWarn)
164172
case l >= slog.LevelInfo:
165-
style = colorLevelInfo
173+
style = e.opts.Theme.LevelInfo()
166174
str = "INF"
167175
delta = int(l - slog.LevelInfo)
168176
case l >= slog.LevelDebug:
169-
style = colorLevelDebug
177+
style = e.opts.Theme.LevelDebug()
170178
str = "DBG"
171179
delta = int(l - slog.LevelDebug)
172180
default:
173-
style = bold
181+
style = e.opts.Theme.LevelDebug()
174182
str = "DBG"
175183
delta = int(l - slog.LevelDebug)
176184
}

handler.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@ type HandlerOptions struct {
3535

3636
// TimeFormat is the format used for time.DateTime
3737
TimeFormat string
38+
39+
// Theme defines the colorized output using ANSI escape sequences
40+
Theme Theme
3841
}
3942

4043
type Handler struct {
41-
opts *HandlerOptions
44+
opts HandlerOptions
4245
out io.Writer
4346
group string
4447
context buffer
@@ -60,13 +63,15 @@ func NewHandler(out io.Writer, opts *HandlerOptions) *Handler {
6063
if opts.TimeFormat == "" {
6164
opts.TimeFormat = time.DateTime
6265
}
63-
opt := *opts // Copy struct
66+
if opts.Theme == nil {
67+
opts.Theme = NewDefaultTheme()
68+
}
6469
return &Handler{
65-
opts: &opt,
70+
opts: *opts, // Copy struct
6671
out: out,
6772
group: "",
6873
context: nil,
69-
enc: &encoder{noColor: opt.NoColor, timeFormat: opt.TimeFormat},
74+
enc: &encoder{opts: *opts},
7075
}
7176
}
7277

@@ -84,7 +89,7 @@ func (h *Handler) Handle(_ context.Context, rec slog.Record) error {
8489
if h.opts.AddSource && rec.PC > 0 {
8590
h.enc.writeSource(buf, rec.PC, cwd)
8691
}
87-
h.enc.writeMessage(buf, rec.Message)
92+
h.enc.writeMessage(buf, rec.Level, rec.Message)
8893
buf.copy(&h.context)
8994
rec.Attrs(func(a slog.Attr) bool {
9095
h.enc.writeAttr(buf, a, h.group)

0 commit comments

Comments
 (0)