mirror of
https://github.com/alecthomas/chroma.git
synced 2025-03-19 21:10:15 +02:00
Support for highlighting ranges of lines.
This commit is contained in:
parent
3f230ec717
commit
a5637e60b2
@ -40,8 +40,9 @@ var (
|
||||
htmlInlineStyleFlag = kingpin.Flag("html-inline-styles", "Output HTML with inline styles (no classes).").Bool()
|
||||
htmlTabWidthFlag = kingpin.Flag("html-tab-width", "Set the HTML tab width.").Default("8").Int()
|
||||
htmlLinesFlag = kingpin.Flag("html-line-numbers", "Include line numbers in output.").Bool()
|
||||
htmlHighlightStyleFlag = kingpin.Flag("html-highlight-style", "Style used for highlighting lines.").Default("bg:#yellow").String()
|
||||
htmlHighlightFlag = kingpin.Flag("html-highlight", "Highlight these ranges (N:M).").Strings()
|
||||
htmlLinesStyleFlag = kingpin.Flag("html-line-numbers-style", "Style for line numbers.").Default("#888").String()
|
||||
htmlHighlightFlag = kingpin.Flag("html-highlight", "Highlight these lines.").PlaceHolder("N[:M][,...]").String()
|
||||
htmlHighlightStyleFlag = kingpin.Flag("html-highlight-style", "Style used for highlighting lines.").Default("bg:#282828").String()
|
||||
|
||||
filesArgs = kingpin.Arg("files", "Files to highlight.").ExistingFiles()
|
||||
)
|
||||
@ -94,6 +95,16 @@ command, for Go.
|
||||
if *htmlFlag {
|
||||
*formatterFlag = "html"
|
||||
}
|
||||
|
||||
// Retrieve user-specified style, clone it, and add some overrides.
|
||||
style := styles.Get(*styleFlag).Clone()
|
||||
if *htmlHighlightStyleFlag != "" {
|
||||
style.Add(chroma.LineHighlight, *htmlHighlightStyleFlag)
|
||||
}
|
||||
if *htmlLinesStyleFlag != "" {
|
||||
style.Add(chroma.LineNumbers, *htmlLinesStyleFlag)
|
||||
}
|
||||
|
||||
if *formatterFlag == "html" {
|
||||
options := []html.Option{html.TabWidth(*htmlTabWidthFlag)}
|
||||
if *htmlPrefixFlag != "" {
|
||||
@ -103,7 +114,7 @@ command, for Go.
|
||||
// Dump styles.
|
||||
if *htmlStylesFlag {
|
||||
formatter := html.New(html.WithClasses())
|
||||
formatter.WriteCSS(w, styles.Get(*styleFlag))
|
||||
formatter.WriteCSS(w, style)
|
||||
return
|
||||
}
|
||||
if !*htmlInlineStyleFlag {
|
||||
@ -117,22 +128,25 @@ command, for Go.
|
||||
}
|
||||
if len(*htmlHighlightFlag) > 0 {
|
||||
ranges := [][2]int{}
|
||||
for _, span := range *htmlHighlightFlag {
|
||||
for _, span := range strings.Split(*htmlHighlightFlag, ",") {
|
||||
parts := strings.Split(span, ":")
|
||||
if len(parts) != 2 {
|
||||
kingpin.Fatalf("range should be N:M, not %q", span)
|
||||
if len(parts) > 2 {
|
||||
kingpin.Fatalf("range should be N[:M], not %q", span)
|
||||
}
|
||||
start, err := strconv.ParseInt(parts[0], 10, 64)
|
||||
kingpin.FatalIfError(err, "min value of range should be integer not %q", parts[0])
|
||||
end, err := strconv.ParseInt(parts[0], 10, 64)
|
||||
kingpin.FatalIfError(err, "max value of range should be integer not %q", parts[0])
|
||||
end := start
|
||||
if len(parts) == 2 {
|
||||
end, err = strconv.ParseInt(parts[1], 10, 64)
|
||||
kingpin.FatalIfError(err, "max value of range should be integer not %q", parts[1])
|
||||
}
|
||||
ranges = append(ranges, [2]int{int(start), int(end)})
|
||||
}
|
||||
options = append(options, html.HighlightLines(*htmlHighlightStyleFlag, ranges))
|
||||
options = append(options, html.HighlightLines(ranges))
|
||||
}
|
||||
formatters.Register("html", html.New(options...))
|
||||
}
|
||||
writer := getWriter(w)
|
||||
writer := getWriter(w, style)
|
||||
if len(*filesArgs) == 0 {
|
||||
contents, err := ioutil.ReadAll(os.Stdin)
|
||||
kingpin.FatalIfError(err, "")
|
||||
@ -201,8 +215,7 @@ func selexer(path, contents string) (lexer chroma.Lexer) {
|
||||
return lexers.Analyse(contents)
|
||||
}
|
||||
|
||||
func getWriter(w io.Writer) func(*chroma.Token) {
|
||||
style := styles.Get(*styleFlag)
|
||||
func getWriter(w io.Writer, style *chroma.Style) func(*chroma.Token) {
|
||||
formatter := formatters.Get(*formatterFlag)
|
||||
// formatter := formatters.TTY8
|
||||
writer, err := formatter.Format(w, style)
|
||||
|
@ -32,12 +32,11 @@ func WithLineNumbers() Option {
|
||||
}
|
||||
}
|
||||
|
||||
// HighlightLines higlights the given line ranges.
|
||||
// HighlightLines higlights the given line ranges with the Highlight style.
|
||||
//
|
||||
// A range is the beginning and ending of a range as 1-based line numbers, inclusive.
|
||||
func HighlightLines(style string, ranges [][2]int) Option {
|
||||
func HighlightLines(ranges [][2]int) Option {
|
||||
return func(f *Formatter) {
|
||||
f.highlightStyle = style
|
||||
f.highlightRanges = ranges
|
||||
sort.Sort(f.highlightRanges)
|
||||
}
|
||||
@ -59,7 +58,6 @@ type Formatter struct {
|
||||
classes bool
|
||||
tabWidth int
|
||||
lineNumbers bool
|
||||
highlightStyle string
|
||||
highlightRanges highlightRanges
|
||||
}
|
||||
|
||||
@ -104,7 +102,21 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []*chroma
|
||||
fmt.Fprintf(w, "<pre%s>\n", f.styleAttr(css, chroma.Background))
|
||||
lines := splitTokensIntoLines(tokens)
|
||||
lineDigits := len(fmt.Sprintf("%d", len(lines)))
|
||||
highlightIndex := 0
|
||||
for line, tokens := range lines {
|
||||
highlight := false
|
||||
for highlightIndex < len(f.highlightRanges) && line+1 > f.highlightRanges[highlightIndex][1] {
|
||||
highlightIndex++
|
||||
}
|
||||
if highlightIndex < len(f.highlightRanges) {
|
||||
hrange := f.highlightRanges[highlightIndex]
|
||||
if line+1 >= hrange[0] && line+1 <= hrange[1] {
|
||||
highlight = true
|
||||
}
|
||||
}
|
||||
if highlight {
|
||||
fmt.Fprintf(w, "<span class=\"hl\">")
|
||||
}
|
||||
if f.lineNumbers {
|
||||
fmt.Fprintf(w, "<span class=\"ln\">%*d</span>", lineDigits, line+1)
|
||||
}
|
||||
@ -117,6 +129,9 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []*chroma
|
||||
}
|
||||
fmt.Fprint(w, html)
|
||||
}
|
||||
if highlight {
|
||||
fmt.Fprintf(w, "</span>")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprint(w, "</pre>\n")
|
||||
@ -134,7 +149,7 @@ func (f *Formatter) class(tt chroma.TokenType) string {
|
||||
return "chroma"
|
||||
case chroma.LineNumbers:
|
||||
return "ln"
|
||||
case chroma.Highlight:
|
||||
case chroma.LineHighlight:
|
||||
return "hl"
|
||||
}
|
||||
if tt < 0 {
|
||||
@ -173,11 +188,6 @@ func (f *Formatter) WriteCSS(w io.Writer, style *chroma.Style) error {
|
||||
if _, err := fmt.Fprintf(w, "/* %s */ .chroma { %s }\n", chroma.Background, css[chroma.Background]); err != nil {
|
||||
return err
|
||||
}
|
||||
// No line-numbers, add a default.
|
||||
if _, ok := css[chroma.LineNumbers]; !ok {
|
||||
css[chroma.LineNumbers] = "color: #888"
|
||||
}
|
||||
css[chroma.LineNumbers] += "; margin-right: 0.5em"
|
||||
tts := []int{}
|
||||
for tt := range css {
|
||||
tts = append(tts, int(tt))
|
||||
@ -199,11 +209,6 @@ func (f *Formatter) WriteCSS(w io.Writer, style *chroma.Style) error {
|
||||
func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string {
|
||||
bg := style.Get(chroma.Background)
|
||||
classes := map[chroma.TokenType]string{}
|
||||
// Insert highlight colour if needed.
|
||||
if len(f.highlightRanges) > 0 {
|
||||
highlight := chroma.ParseStyleEntry(bg, f.highlightStyle).Sub(bg)
|
||||
classes[chroma.Highlight] = StyleEntryToCSS(highlight)
|
||||
}
|
||||
// Convert the style.
|
||||
for t := range style.Entries {
|
||||
e := style.Entries[t]
|
||||
@ -213,6 +218,8 @@ func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string
|
||||
classes[t] = StyleEntryToCSS(e)
|
||||
}
|
||||
classes[chroma.Background] += f.tabWidthStyle()
|
||||
classes[chroma.LineNumbers] += "; margin-right: 0.5em"
|
||||
classes[chroma.LineHighlight] += "; display: block; width: 100%"
|
||||
return classes
|
||||
}
|
||||
|
||||
|
19
style.go
19
style.go
@ -17,6 +17,13 @@ type StyleEntry struct {
|
||||
Underline bool
|
||||
}
|
||||
|
||||
// Clone this StyleEntry.
|
||||
func (s *StyleEntry) Clone() *StyleEntry {
|
||||
clone := &StyleEntry{}
|
||||
*clone = *s
|
||||
return clone
|
||||
}
|
||||
|
||||
func (s *StyleEntry) String() string {
|
||||
out := []string{}
|
||||
if s.Bold {
|
||||
@ -89,6 +96,18 @@ type Style struct {
|
||||
Entries map[TokenType]*StyleEntry
|
||||
}
|
||||
|
||||
// Clone this style. The clone can then be safely modified.
|
||||
func (s *Style) Clone() *Style {
|
||||
clone := &Style{
|
||||
Name: s.Name,
|
||||
Entries: map[TokenType]*StyleEntry{},
|
||||
}
|
||||
for tt, e := range s.Entries {
|
||||
clone.Entries[tt] = e.Clone()
|
||||
}
|
||||
return clone
|
||||
}
|
||||
|
||||
// Get a style entry. Will try sub-category or category if an exact match is not found, and
|
||||
// finally return the entry mapped to `InheritStyle`.
|
||||
func (s *Style) Get(ttype TokenType) *StyleEntry {
|
||||
|
@ -4,102 +4,102 @@ package chroma
|
||||
|
||||
import "fmt"
|
||||
|
||||
const _TokenType_name = "EOFNoneOtherErrorEscapeHighlightLineNumbersBackgroundKeywordKeywordConstantKeywordDeclarationKeywordNamespaceKeywordPseudoKeywordReservedKeywordTypeNameNameAttributeNameBuiltinNameBuiltinPseudoNameClassNameConstantNameDecoratorNameEntityNameExceptionNameFunctionNameFunctionMagicNameKeywordNameLabelNameNamespaceNameOperatorNameOtherNamePseudoNamePropertyNameTagNameVariableNameVariableAnonymousNameVariableClassNameVariableGlobalNameVariableInstanceNameVariableMagicLiteralLiteralDateLiteralOtherLiteralStringLiteralStringAffixLiteralStringAtomLiteralStringBacktickLiteralStringBooleanLiteralStringCharLiteralStringDelimiterLiteralStringDocLiteralStringDoubleLiteralStringEscapeLiteralStringHeredocLiteralStringInterpolLiteralStringNameLiteralStringOtherLiteralStringRegexLiteralStringSingleLiteralStringSymbolLiteralNumberLiteralNumberBinLiteralNumberFloatLiteralNumberHexLiteralNumberIntegerLiteralNumberIntegerLongLiteralNumberOctOperatorOperatorWordPunctuationCommentCommentHashbangCommentMultilineCommentSingleCommentSpecialCommentPreprocCommentPreprocFileGenericGenericDeletedGenericEmphGenericErrorGenericHeadingGenericInsertedGenericOutputGenericPromptGenericStrongGenericSubheadingGenericTracebackGenericUnderlineTextTextWhitespaceTextSymbolTextPunctuation"
|
||||
const _TokenType_name = "EOFNoneOtherErrorHighlightLineHighlightLineNumbersBackgroundKeywordKeywordConstantKeywordDeclarationKeywordNamespaceKeywordPseudoKeywordReservedKeywordTypeNameNameAttributeNameBuiltinNameBuiltinPseudoNameClassNameConstantNameDecoratorNameEntityNameExceptionNameFunctionNameFunctionMagicNameKeywordNameLabelNameNamespaceNameOperatorNameOtherNamePseudoNamePropertyNameTagNameVariableNameVariableAnonymousNameVariableClassNameVariableGlobalNameVariableInstanceNameVariableMagicLiteralLiteralDateLiteralOtherLiteralStringLiteralStringAffixLiteralStringAtomLiteralStringBacktickLiteralStringBooleanLiteralStringCharLiteralStringDelimiterLiteralStringDocLiteralStringDoubleLiteralStringEscapeLiteralStringHeredocLiteralStringInterpolLiteralStringNameLiteralStringOtherLiteralStringRegexLiteralStringSingleLiteralStringSymbolLiteralNumberLiteralNumberBinLiteralNumberFloatLiteralNumberHexLiteralNumberIntegerLiteralNumberIntegerLongLiteralNumberOctOperatorOperatorWordPunctuationCommentCommentHashbangCommentMultilineCommentSingleCommentSpecialCommentPreprocCommentPreprocFileGenericGenericDeletedGenericEmphGenericErrorGenericHeadingGenericInsertedGenericOutputGenericPromptGenericStrongGenericSubheadingGenericTracebackGenericUnderlineTextTextWhitespaceTextSymbolTextPunctuation"
|
||||
|
||||
var _TokenType_map = map[TokenType]string{
|
||||
-8: _TokenType_name[0:3],
|
||||
-7: _TokenType_name[3:7],
|
||||
-6: _TokenType_name[7:12],
|
||||
-5: _TokenType_name[12:17],
|
||||
-4: _TokenType_name[17:23],
|
||||
-3: _TokenType_name[23:32],
|
||||
-2: _TokenType_name[32:43],
|
||||
-1: _TokenType_name[43:53],
|
||||
1000: _TokenType_name[53:60],
|
||||
1001: _TokenType_name[60:75],
|
||||
1002: _TokenType_name[75:93],
|
||||
1003: _TokenType_name[93:109],
|
||||
1004: _TokenType_name[109:122],
|
||||
1005: _TokenType_name[122:137],
|
||||
1006: _TokenType_name[137:148],
|
||||
2000: _TokenType_name[148:152],
|
||||
2001: _TokenType_name[152:165],
|
||||
2002: _TokenType_name[165:176],
|
||||
2003: _TokenType_name[176:193],
|
||||
2004: _TokenType_name[193:202],
|
||||
2005: _TokenType_name[202:214],
|
||||
2006: _TokenType_name[214:227],
|
||||
2007: _TokenType_name[227:237],
|
||||
2008: _TokenType_name[237:250],
|
||||
2009: _TokenType_name[250:262],
|
||||
2010: _TokenType_name[262:279],
|
||||
2011: _TokenType_name[279:290],
|
||||
2012: _TokenType_name[290:299],
|
||||
2013: _TokenType_name[299:312],
|
||||
2014: _TokenType_name[312:324],
|
||||
2015: _TokenType_name[324:333],
|
||||
2016: _TokenType_name[333:343],
|
||||
2017: _TokenType_name[343:355],
|
||||
2018: _TokenType_name[355:362],
|
||||
2019: _TokenType_name[362:374],
|
||||
2020: _TokenType_name[374:395],
|
||||
2021: _TokenType_name[395:412],
|
||||
2022: _TokenType_name[412:430],
|
||||
2023: _TokenType_name[430:450],
|
||||
2024: _TokenType_name[450:467],
|
||||
3000: _TokenType_name[467:474],
|
||||
3001: _TokenType_name[474:485],
|
||||
3002: _TokenType_name[485:497],
|
||||
3100: _TokenType_name[497:510],
|
||||
3101: _TokenType_name[510:528],
|
||||
3102: _TokenType_name[528:545],
|
||||
3103: _TokenType_name[545:566],
|
||||
3104: _TokenType_name[566:586],
|
||||
3105: _TokenType_name[586:603],
|
||||
3106: _TokenType_name[603:625],
|
||||
3107: _TokenType_name[625:641],
|
||||
3108: _TokenType_name[641:660],
|
||||
3109: _TokenType_name[660:679],
|
||||
3110: _TokenType_name[679:699],
|
||||
3111: _TokenType_name[699:720],
|
||||
3112: _TokenType_name[720:737],
|
||||
3113: _TokenType_name[737:755],
|
||||
3114: _TokenType_name[755:773],
|
||||
3115: _TokenType_name[773:792],
|
||||
3116: _TokenType_name[792:811],
|
||||
3200: _TokenType_name[811:824],
|
||||
3201: _TokenType_name[824:840],
|
||||
3202: _TokenType_name[840:858],
|
||||
3203: _TokenType_name[858:874],
|
||||
3204: _TokenType_name[874:894],
|
||||
3205: _TokenType_name[894:918],
|
||||
3206: _TokenType_name[918:934],
|
||||
4000: _TokenType_name[934:942],
|
||||
4001: _TokenType_name[942:954],
|
||||
5000: _TokenType_name[954:965],
|
||||
6000: _TokenType_name[965:972],
|
||||
6001: _TokenType_name[972:987],
|
||||
6002: _TokenType_name[987:1003],
|
||||
6003: _TokenType_name[1003:1016],
|
||||
6004: _TokenType_name[1016:1030],
|
||||
6100: _TokenType_name[1030:1044],
|
||||
6101: _TokenType_name[1044:1062],
|
||||
7000: _TokenType_name[1062:1069],
|
||||
7001: _TokenType_name[1069:1083],
|
||||
7002: _TokenType_name[1083:1094],
|
||||
7003: _TokenType_name[1094:1106],
|
||||
7004: _TokenType_name[1106:1120],
|
||||
7005: _TokenType_name[1120:1135],
|
||||
7006: _TokenType_name[1135:1148],
|
||||
7007: _TokenType_name[1148:1161],
|
||||
7008: _TokenType_name[1161:1174],
|
||||
7009: _TokenType_name[1174:1191],
|
||||
7010: _TokenType_name[1191:1207],
|
||||
7011: _TokenType_name[1207:1223],
|
||||
8000: _TokenType_name[1223:1227],
|
||||
8001: _TokenType_name[1227:1241],
|
||||
8002: _TokenType_name[1241:1251],
|
||||
8003: _TokenType_name[1251:1266],
|
||||
-4: _TokenType_name[17:26],
|
||||
-3: _TokenType_name[26:39],
|
||||
-2: _TokenType_name[39:50],
|
||||
-1: _TokenType_name[50:60],
|
||||
1000: _TokenType_name[60:67],
|
||||
1001: _TokenType_name[67:82],
|
||||
1002: _TokenType_name[82:100],
|
||||
1003: _TokenType_name[100:116],
|
||||
1004: _TokenType_name[116:129],
|
||||
1005: _TokenType_name[129:144],
|
||||
1006: _TokenType_name[144:155],
|
||||
2000: _TokenType_name[155:159],
|
||||
2001: _TokenType_name[159:172],
|
||||
2002: _TokenType_name[172:183],
|
||||
2003: _TokenType_name[183:200],
|
||||
2004: _TokenType_name[200:209],
|
||||
2005: _TokenType_name[209:221],
|
||||
2006: _TokenType_name[221:234],
|
||||
2007: _TokenType_name[234:244],
|
||||
2008: _TokenType_name[244:257],
|
||||
2009: _TokenType_name[257:269],
|
||||
2010: _TokenType_name[269:286],
|
||||
2011: _TokenType_name[286:297],
|
||||
2012: _TokenType_name[297:306],
|
||||
2013: _TokenType_name[306:319],
|
||||
2014: _TokenType_name[319:331],
|
||||
2015: _TokenType_name[331:340],
|
||||
2016: _TokenType_name[340:350],
|
||||
2017: _TokenType_name[350:362],
|
||||
2018: _TokenType_name[362:369],
|
||||
2019: _TokenType_name[369:381],
|
||||
2020: _TokenType_name[381:402],
|
||||
2021: _TokenType_name[402:419],
|
||||
2022: _TokenType_name[419:437],
|
||||
2023: _TokenType_name[437:457],
|
||||
2024: _TokenType_name[457:474],
|
||||
3000: _TokenType_name[474:481],
|
||||
3001: _TokenType_name[481:492],
|
||||
3002: _TokenType_name[492:504],
|
||||
3100: _TokenType_name[504:517],
|
||||
3101: _TokenType_name[517:535],
|
||||
3102: _TokenType_name[535:552],
|
||||
3103: _TokenType_name[552:573],
|
||||
3104: _TokenType_name[573:593],
|
||||
3105: _TokenType_name[593:610],
|
||||
3106: _TokenType_name[610:632],
|
||||
3107: _TokenType_name[632:648],
|
||||
3108: _TokenType_name[648:667],
|
||||
3109: _TokenType_name[667:686],
|
||||
3110: _TokenType_name[686:706],
|
||||
3111: _TokenType_name[706:727],
|
||||
3112: _TokenType_name[727:744],
|
||||
3113: _TokenType_name[744:762],
|
||||
3114: _TokenType_name[762:780],
|
||||
3115: _TokenType_name[780:799],
|
||||
3116: _TokenType_name[799:818],
|
||||
3200: _TokenType_name[818:831],
|
||||
3201: _TokenType_name[831:847],
|
||||
3202: _TokenType_name[847:865],
|
||||
3203: _TokenType_name[865:881],
|
||||
3204: _TokenType_name[881:901],
|
||||
3205: _TokenType_name[901:925],
|
||||
3206: _TokenType_name[925:941],
|
||||
4000: _TokenType_name[941:949],
|
||||
4001: _TokenType_name[949:961],
|
||||
5000: _TokenType_name[961:972],
|
||||
6000: _TokenType_name[972:979],
|
||||
6001: _TokenType_name[979:994],
|
||||
6002: _TokenType_name[994:1010],
|
||||
6003: _TokenType_name[1010:1023],
|
||||
6004: _TokenType_name[1023:1037],
|
||||
6100: _TokenType_name[1037:1051],
|
||||
6101: _TokenType_name[1051:1069],
|
||||
7000: _TokenType_name[1069:1076],
|
||||
7001: _TokenType_name[1076:1090],
|
||||
7002: _TokenType_name[1090:1101],
|
||||
7003: _TokenType_name[1101:1113],
|
||||
7004: _TokenType_name[1113:1127],
|
||||
7005: _TokenType_name[1127:1142],
|
||||
7006: _TokenType_name[1142:1155],
|
||||
7007: _TokenType_name[1155:1168],
|
||||
7008: _TokenType_name[1168:1181],
|
||||
7009: _TokenType_name[1181:1198],
|
||||
7010: _TokenType_name[1198:1214],
|
||||
7011: _TokenType_name[1214:1230],
|
||||
8000: _TokenType_name[1230:1234],
|
||||
8001: _TokenType_name[1234:1248],
|
||||
8002: _TokenType_name[1248:1258],
|
||||
8003: _TokenType_name[1258:1273],
|
||||
}
|
||||
|
||||
func (i TokenType) String() string {
|
||||
|
10
types.go
10
types.go
@ -15,13 +15,21 @@ type TokenType int
|
||||
|
||||
// Meta token types.
|
||||
const (
|
||||
// Default background style.
|
||||
Background TokenType = -1 - iota
|
||||
// Line numbers in output.
|
||||
LineNumbers
|
||||
// Line higlight style.
|
||||
LineHighlight
|
||||
// Character highlight style.
|
||||
Highlight
|
||||
Escape
|
||||
// Input that could not be tokenised.
|
||||
Error
|
||||
// Other is used by the Delegate lexer to indicate which tokens should be handled by the delegate.
|
||||
Other
|
||||
// No highlighting.
|
||||
None
|
||||
// Final token.
|
||||
EOF
|
||||
)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user