turbo-editors/turbo-corepublic Fork 0
28d59854361aeda8541d853093e732126f3d7bff
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

class.go · 136 lines · 4.7 KBGo Blame HistoryRaw
🛟 Updated. 28d5985 k33g 18h ago1// Package syntax colours source code.
2//
3// It colours the languages every editor built on this library meets whatever it
4// is for — TOML, Markdown, JavaScript, HTML, shell scripts, YAML, XML and
5// Dockerfiles — and it is the place an editor registers the language it is
6// *for*: Turbo Go registers Go, Turbo Rust registers Rust, and neither is known
7// here.
8//
9// Every scanner turns its input into per-line spans the editor can draw, and
10// every one of them is deliberately tolerant: text under the cursor is broken
11// most of the time it is being typed, and a highlighter that gives up on
12// invalid input is a highlighter that flickers off.
13//
14// Three things make up the extension point. Definition and Register say what a
15// language is and teach it to this package; LineScanner and ScanLines are what
16// a scanner is written against; and LineIndex is for a scanner that works in
17// byte offsets instead, which is what a tokeniser like go/scanner gives you.
18//
19// A file is recognised by its extension, then by its name — which is how a
20// Dockerfile, which has no extension, is found — and failing both by a shebang.
21//
22// The package depends on theme only for the vocabulary of style keys, so that a
23// token class and the colour it resolves to are named in one place.
24package syntax
25
26import "codeberg.org/turbo-editors/turbo-core/theme"
27
28// Class is what a run of source text is, in colouring terms.
29//
30// It is deliberately coarser than any one language's token set: the editor
31// needs to tell a keyword from a string, not an ADD from a SUB. Most classes
32// are shared across languages — a string is a string in all of them — and only
33// the last five belong to markup, because nothing in a programming language
34// reads as a heading.
35//
36// The set is fixed. A language registered from outside this package colours
37// itself with these classes and no others, which is what lets one theme colour
38// every language an editor built on this library will ever learn.
39type Class uint8
40
41// The classes a token can fall into.
42const (
43 // ClassIdentifier is the zero value, so text nothing else claims is drawn
44 // as a plain identifier.
45 ClassIdentifier Class = iota
46 ClassKeyword
47 ClassType
48 ClassBuiltin
49 ClassConstant
50 ClassFunction
51 ClassString
52 ClassChar
53 ClassNumber
54 ClassComment
55 ClassOperator
56 ClassPunctuation
57
58 // ClassHeading is a Markdown heading, whole line included.
59 ClassHeading
60 // ClassTag is an HTML element name, and the angle brackets around it.
61 ClassTag
62 // ClassAttribute is an HTML attribute's name.
63 ClassAttribute
64 // ClassEmphasis is Markdown bold or italic text.
65 ClassEmphasis
66 // ClassLink is a Markdown link or image, both its text and its target.
67 ClassLink
68)
69
70// styleKeys maps each class onto the theme key that colours it.
71var styleKeys = [...]string{
72 ClassIdentifier: theme.KeySyntaxIdentifier,
73 ClassKeyword: theme.KeySyntaxKeyword,
74 ClassType: theme.KeySyntaxType,
75 ClassBuiltin: theme.KeySyntaxBuiltin,
76 ClassConstant: theme.KeySyntaxConstant,
77 ClassFunction: theme.KeySyntaxFunction,
78 ClassString: theme.KeySyntaxString,
79 ClassChar: theme.KeySyntaxChar,
80 ClassNumber: theme.KeySyntaxNumber,
81 ClassComment: theme.KeySyntaxComment,
82 ClassOperator: theme.KeySyntaxOperator,
83 ClassPunctuation: theme.KeySyntaxPunctuation,
84 ClassHeading: theme.KeySyntaxHeading,
85 ClassTag: theme.KeySyntaxTag,
86 ClassAttribute: theme.KeySyntaxAttribute,
87 ClassEmphasis: theme.KeySyntaxEmphasis,
88 ClassLink: theme.KeySyntaxLink,
89}
90
91// StyleKey returns the theme key that colours this class.
92//
93// style := th.Style(syntax.ClassKeyword.StyleKey())
94func (c Class) StyleKey() string {
95 if int(c) >= len(styleKeys) {
96 return theme.KeySyntaxIdentifier
97 }
98 return styleKeys[c]
99}
100
101// String returns the class name, for tests and for debugging.
102func (c Class) String() string {
103 names := [...]string{
104 ClassIdentifier: "identifier",
105 ClassKeyword: "keyword",
106 ClassType: "type",
107 ClassBuiltin: "builtin",
108 ClassConstant: "constant",
109 ClassFunction: "function",
110 ClassString: "string",
111 ClassChar: "char",
112 ClassNumber: "number",
113 ClassComment: "comment",
114 ClassOperator: "operator",
115 ClassPunctuation: "punctuation",
116 ClassHeading: "heading",
117 ClassTag: "tag",
118 ClassAttribute: "attribute",
119 ClassEmphasis: "emphasis",
120 ClassLink: "link",
121 }
122 if int(c) >= len(names) {
123 return "unknown"
124 }
125 return names[c]
126}
127
128// Span is a run of runes on a single line that share one class.
129//
130// Columns are rune offsets into the line: Start is included, End excluded,
131// matching the convention used everywhere else in the editor.
132type Span struct {
133 Start int
134 End int
135 Class Class
136}