turbo-editors/turbo-gopublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-go.git
git clone ssh://git@rickub.com/turbo-editors/turbo-go.git

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

languages.md · 238 lines · 12.0 KBmarkdown Blame HistoryRaw
📦 Turbo Go 3d7798b k33g 12h ago1# Reference: languages coloured
2
3> Neutral description of which files Turbo Go colours, how it decides, and what each scanner recognises.
4
5## Recognition
6
7A file's **extension** decides whenever it is one of these:
8
9| Extension | Language |
10| --- | --- |
11| `.go` | Go |
12| `.toml` | TOML |
13| `.yaml`, `.yml` | YAML |
14| `.md`, `.markdown` | Markdown |
15| `.js`, `.mjs`, `.cjs` | JavaScript |
16| `.html`, `.htm` | HTML |
17| `.xml`, `.xsd`, `.xsl`, `.xslt`, `.svg`, `.plist`, `.csproj`, `.pom` | XML |
18| `.sh`, `.bash`, `.zsh` | Shell |
19| `.dockerfile`, `.containerfile` | Dockerfile |
20
21Extensions are matched case-insensitively, and only the last one counts: `main.go.backup` is not Go.
22
23A file whose extension decides nothing is looked up by **name** next. Only files that carry no useful extension need this:
24
25| Name | Language |
26| --- | --- |
27| `Dockerfile`, `Containerfile` | Dockerfile |
28
29A name matches on the whole of it or on the part before the first dot, ignoring case — so `Dockerfile`, `dockerfile` and `Dockerfile.dev` are all recognised, while `Dockerfile.md` is Markdown, because the extension is consulted first.
30
31A file that neither table claims is a **shell script** when its first line is a shebang naming a shell — `sh`, `bash`, `zsh`, `dash` or `ksh`, as a path element or as the argument to `env`. That is what colours `configure`, a git hook, or a script somebody renamed.
32
33| First line | Result |
34| --- | --- |
35| `#!/bin/sh` | Shell |
36| `#!/usr/bin/env bash` | Shell |
37| `#!/usr/bin/env -S bash -e` | Shell |
38| `#!/usr/bin/env python3` | Not coloured |
39| Anything not starting `#!` | Not coloured |
40
41The order is fixed — extension, then name, then first line — and the first to decide wins: a `.go` file starting with a shebang is Go.
42
43Everything else is shown in plain text. That is not an error — opening a PNG in the editor is not a mistake, it is just not coloured.
44
45## Classes
46
47Every scanner produces the same vocabulary of classes, and each maps to one theme key.
48
49| Class | Theme key | Produced by |
50| --- | --- | --- |
51| `identifier` | `syntax.identifier` | Go, TOML, JavaScript, shell, YAML, Dockerfile |
52| `keyword` | `syntax.keyword` | Go, JavaScript, shell, HTML (doctype), XML, Dockerfile |
53| `type` | `syntax.type` | Go, TOML (table headers), YAML (tags) |
54| `builtin` | `syntax.builtin` | Go, JavaScript, shell (builtins and expansions), YAML (anchors and aliases), Dockerfile (variables) |
55| `constant` | `syntax.constant` | Go, TOML, JavaScript, shell, YAML, HTML and XML (entities) |
56| `function` | `syntax.function` | Go, JavaScript, shell (the command) |
57| `string` | `syntax.string` | all |
58| `char` | `syntax.char` | Go |
59| `number` | `syntax.number` | Go, TOML, JavaScript, shell, YAML, Dockerfile |
60| `comment` | `syntax.comment` | Go, TOML, JavaScript, shell, HTML, YAML, XML, Dockerfile |
61| `operator` | `syntax.operator` | Go, TOML, JavaScript, shell, HTML, YAML (block scalar headers), XML, Dockerfile |
62| `punctuation` | `syntax.punctuation` | Go, TOML, JavaScript, shell, Markdown, YAML, Dockerfile |
63| `heading` | `syntax.heading` | Markdown |
64| `tag` | `syntax.tag` | HTML, XML |
65| `attribute` | `syntax.attribute` | HTML, XML, Dockerfile (flags) |
66| `emphasis` | `syntax.emphasis` | Markdown |
67| `link` | `syntax.link` | Markdown |
68
69## Go
70
71Tokenised by `go/scanner`, the lexer the Go toolchain itself uses. See [Colouring and completion](../explanation/colouring-and-completion.md).
72
73## TOML
74
75| Recognised | As |
76| --- | --- |
77| `# comment` | comment |
78| `[table]`, `[[array]]` | the name as a type, the brackets as punctuation |
79| `key =` | identifier, then operator |
80| `"basic"`, `'literal'`, `"""multi-line"""`, `'''multi-line'''` | string |
81| `true`, `false` | constant |
82| numbers, dates, times, `inf`, `nan` | number |
83
84## YAML
85
86A compose file, a Kubernetes manifest and a CI workflow are all this: there is no separate dialect, because a dialect would be somebody else's schema to keep in step with.
87
88| Recognised | As |
89| --- | --- |
90| `# comment` | comment |
91| `key:` before a space or the end of the line | the key as an identifier, the colon as punctuation |
92| `"quoted": 1`, `'quoted': 1` | the quoted key as an identifier |
93| `- ` opening a sequence entry | punctuation |
94| `"…"`, `'…'` | string |
95| `true`, `false`, `yes`, `no`, `on`, `off`, `null` | constant, whatever their case |
96| numbers, dates and times written without quotes | number |
97| `&anchor`, `*alias` | builtin |
98| `!!str`, `!Custom` | type |
99| `---`, `...` | the whole line as punctuation |
100| `{`, `}`, `[`, `]`, `,` | punctuation |
101| `\|`, `>`, with their chomping and indentation indicators | the header as an operator, the body as a string |
102
103**A colon is a separator only when a space or the end of the line follows it.** `image: nginx:1.27` is a key and one value, and `url: http://example.com/x` is a key and one URL — colouring the inner colons as separators would put every image tag and every URL in three colours.
104
105**A block scalar's extent is decided by indentation**, not by a delimiter. The first content line after `|` or `>` fixes the block's indentation; every line indented at least that far belongs to it, and the first line that is not ends it. **A blank line inside a block stays inside it**: a literal scalar keeps its empty lines, and ending the block at the first paragraph break would cut a shell script in a CI file in half.
106
107**A `#` needs a space before it to start a comment**, so `colour: ff#00aa` is one scalar.
108
109| Not recognised | Because |
110| --- | --- |
111| The schema of a compose file, a manifest or a workflow | Colouring `services:` differently from any other key means carrying somebody else's schema, and it goes stale the day they add a key |
112| Multi-document streams as separate documents | `---` is coloured, but nothing is reset at it; nothing in the colouring depends on document boundaries |
113| Whether a bare word is a string or a number to a parser | `1.2.3` is a version to a reader and a string to YAML; the scanner colours what it looks like |
114
115## Markdown
116
117| Recognised | As |
118| --- | --- |
119| `# Heading``###### Heading` | the whole line as a heading |
120| `**bold**`, `__bold__`, `*italic*`, `_italic_` | emphasis |
121| `` `code` `` | string |
122| `[text](target)`, `![alt](src)` | the whole thing as a link |
123| `- `, `* `, `+ `, `1. `, `1) ` | the marker as punctuation |
124| `>` | punctuation |
125| `---`, `***`, `___` | punctuation |
126| ` ``` ` and `~~~` fences | the whole block, opening and closing lines included, as a string |
127
128A fenced block is **one colour whatever language it announces**: ```` ```go ```` does not colour its contents as Go. The run of markers that opens a block must be matched by the same character to close it, so a backtick fence is not closed by a tilde one. An unclosed fence colours to the end of the file.
129
130The run of markers opening emphasis must be matched by a run of the same length, so `**bold**` is one span rather than two italics.
131
132## JavaScript
133
134| Recognised | As |
135| --- | --- |
136| `const`, `let`, `function`, `class`, `async`, `await`, `import`, `export`, … | keyword |
137| `true`, `false`, `null`, `undefined`, `NaN`, `Infinity`, `this` | constant |
138| `console`, `document`, `window`, `Array`, `Object`, `Promise`, `Math`, `JSON`, … | builtin |
139| a name immediately before `(` | function |
140| `"…"`, `'…'` | string |
141| `` `` ``, interpolations included, across lines | string |
142| `//` to end of line, `/* … */` across lines | comment |
143| `42`, `3.14`, `0x1f`, `0b1010`, `0o777`, `1_000_000`, `1e6`, `10n` | number |
144| runs of `+-*/%=<>!&|^~?:` | operator |
145| `()[]{},;.` | punctuation |
146
147**Regular-expression literals are not recognised.** Telling `/x/g` from a division needs to know whether the previous token could end an expression; a wrong guess colours the rest of a line as a string, which is worse than leaving a regex the colour of an operator.
148
149Globals are recognised by name, so a file that shadows `Math` still has it coloured as a builtin — the same rule Go's predeclared identifiers follow.
150
151## HTML
152
153| Recognised | As |
154| --- | --- |
155| `<tag`, `</tag`, `>`, `/>` | tag |
156| attribute names, including `data-*`, `xlink:href`, `@click`, `v-bind.prop` | attribute |
157| `=` | operator |
158| `"…"`, `'…'` | string |
159| `<!-- … -->`, across lines | comment |
160| `&amp;`, `&#169;` | constant |
161| `<!DOCTYPE …>` and other declarations | keyword |
162
163Text between tags is not coloured. A bare `&` with no `;` within 32 characters is left alone, because it is legal text.
164
165**The contents of `<script>` and `<style>` are not coloured** as JavaScript and CSS.
166
167## XML
168
169Its own scanner rather than HTML's, for one reason that matters: CDATA. The whole point of `<![CDATA[ … ]]>` is that its contents are *not* markup, and colouring the tags inside one as tags is exactly backwards.
170
171| Recognised | As |
172| --- | --- |
173| `<?xml version="1.0"?>` and other processing instructions | the target and `?>` as keyword, the pairs between as attributes and strings |
174| `<!DOCTYPE …>` and the other `<!` forms | keyword |
175| `<!-- … -->`, across lines | comment |
176| `<![CDATA[ … ]]>`, across lines | string |
177| `<tag`, `</tag`, `>`, `/>` | tag |
178| `<ns:tag>`, `xsi:type` | the prefix and the local name as **one** span |
179| attribute names | attribute |
180| `=` | operator |
181| `"…"`, `'…'` | string |
182| `&amp;`, `&#169;` | constant |
183
184**A comment and a CDATA section close on different delimiters**, and are carried separately: a `-->` inside a CDATA section does not end it.
185
186**A bare `&` with no semicolon within 32 characters is left alone**, because it is legal text in plenty of documents and swallowing the rest of the line would be the bigger mistake.
187
188Text between tags is not coloured.
189
190## Shell
191
192Applies to `sh`, `bash` and `zsh` alike: the keywords recognised are the ones they share.
193
194| Recognised | As |
195| --- | --- |
196| `if`, `then`, `fi`, `for`, `while`, `case`, `esac`, `function`, `return`, … | keyword |
197| `true`, `false` | constant |
198| `echo`, `printf`, `export`, `local`, `read`, `cd`, `set`, `source`, … | builtin |
199| `$NAME`, `${…}`, `$(…)`, `$1`, `$?`, `$@` | builtin |
200| the **first bare word on a line** | function |
201| every later bare word, and `NAME` in `NAME=value` | identifier |
202| `'…'`, with nothing escaped or expanded inside | string |
203| `"…"`, with the expansions inside it coloured as expansions | string |
204| `#` to end of line | comment |
205
206`$(a $(b) c)` is one span: nesting is counted. An option such as `-euo` is one word, not a minus and a word.
207
208**Heredocs are not recognised.** `<<EOF` and the text after it are coloured as ordinary shell.
209
210## Dockerfile
211
212| Recognised | As |
213| --- | --- |
214| `FROM`, `RUN`, `COPY`, `ADD`, `ARG`, `ENV`, `CMD`, `ENTRYPOINT`, `EXPOSE`, `LABEL`, `USER`, `VOLUME`, `WORKDIR`, `HEALTHCHECK`, `ONBUILD`, `SHELL`, `STOPSIGNAL`, `MAINTAINER` | keyword, in any case |
215| `AS`, `NONE` | keyword |
216| `# comment`, including the `# syntax=` and `# escape=` directives | comment |
217| `--from=builder`, `--chown=me:me` | the flag name as an attribute |
218| `$NAME`, `${NAME}`, `${NAME:-default}` | builtin, as one span to the closing brace |
219| `"…"`, `'…'` | string |
220| a trailing `\` | operator |
221| numbers | number |
222| paths and image references — `/usr/local/bin`, `golang:1.26-alpine` | identifier, as **one** span |
223
224**Only the first word of a line can be an instruction**, and a word that is not one is an argument — which is what keeps a continuation line's first word out of the keyword colour.
225
226**Nothing crosses a line break.** A `\` joins two lines for Docker, but each half still reads as a command and is coloured on its own.
227
228| Not recognised | Because |
229| --- | --- |
230| The shell inside a `RUN` | It would mean running the shell scanner over part of a line and mapping its columns out, and `RUN` may hold any language |
231| Heredocs in a `RUN` | The same reason the shell scanner does not recognise them |
232| Which stage a `--from` names | Nothing here reads the rest of the file |
233
234## See also
235
236- [Theme file format](themes.md) — every key these classes resolve to
237- [Colouring and completion](../explanation/colouring-and-completion.md) — why the scanners are written this way
238- [How to write your own theme](../how-to/write-a-theme.md)