1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
package tui
import "github.com/grindlemire/go-tui/internal/highlight"
type TokenKind int
const (
TokenPlain TokenKind = iota
TokenKeyword
TokenString
TokenComment
TokenNumber
TokenLiteral
TokenType
TokenOperator
TokenKey
)
type CodeHighlighter interface {
Highlight(lang, code string) [][]TextSpan
}
type Palette map[TokenKind]Color
func DefaultPalette() Palette {
return Palette{
TokenKeyword: hexOrDefault("#c678dd"),
TokenString: hexOrDefault("#98c379"),
TokenComment: hexOrDefault("#7f848e"),
TokenNumber: hexOrDefault("#d19a66"),
TokenLiteral: hexOrDefault("#d19a66"),
TokenType: hexOrDefault("#61afef"),
TokenOperator: hexOrDefault("#56b6c2"),
TokenKey: hexOrDefault("#e06c75"),
}
}
func hexOrDefault(hex string) Color {
c, err := HexColor(hex)
if err != nil {
return DefaultColor()
}
return c
}
func NewHighlighter(p Palette) CodeHighlighter {
return &builtinHighlighter{palette: p}
}
type builtinHighlighter struct {
palette Palette
}
func (h *builtinHighlighter) Highlight(lang, code string) [][]TextSpan {
lines := highlight.Tokenize(lang, code)
out := make([][]TextSpan, len(lines))
for i, line := range lines {
spans := make([]TextSpan, 0, len(line))
for _, t := range line {
s := TextSpan{Text: t.Text}
if c, ok := h.palette[mapKind(t.Kind)]; ok {
s.Style = NewStyle().Foreground(c)
}
spans = append(spans, s)
}
out[i] = spans
}
return out
}
func mapKind(k highlight.Kind) TokenKind {
switch k {
case highlight.KindKeyword:
return TokenKeyword
case highlight.KindString:
return TokenString
case highlight.KindComment:
return TokenComment
case highlight.KindNumber:
return TokenNumber
case highlight.KindLiteral:
return TokenLiteral
case highlight.KindType:
return TokenType
case highlight.KindOperator:
return TokenOperator
case highlight.KindKey:
return TokenKey
}
return TokenPlain
}
|