turbo-editors/turbo-corepublic Fork 0
v1.0.2
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.

📦 Turbo Core f3ade8d · on v1.0.2 · k33g · 10h ago
syntax.md · 163 lines · 7.6 KBmarkdown
Blame HistoryOpen raw

Référence : le point d'extension syntaxique

Description neutre et exhaustive de ce que rickub.com/turbo-editors/turbo-core/syntax offre à l'auteur d'un langage.

Language

type Language string

Le nom sous lequel un langage est connu. C'est une chaîne parce qu'il est écrit hors du paquet : un fichier d'extraits se restreint avec languages = ["go"], et un langage enregistré par un éditeur n'est pas quelque chose que la bibliothèque aurait pu numéroter d'avance.

Constante Valeur
LanguageNone ""
LanguageTOML "toml"
LanguageYAML "yaml"
LanguageMarkdown "markdown"
LanguageJavaScript "javascript"
LanguageHTML "html"
LanguageXML "xml"
LanguageDockerfile "dockerfile"
LanguageBash "bash"

Language.String() renvoie le nom, et "none" pour LanguageNone.

Definition

Champ Type Description
Language Language Le nom ; la valeur que LanguageOf renvoie pour un fichier de cette sorte.
Extensions []string Les extensions qui l'identifient, avec leur point, en minuscules.
Filenames []string Des noms de fichiers entiers qui l'identifient, pour les fichiers sans extension utile : "Dockerfile". Un fichier correspond par son nom entier ou par la partie précédant son premier point, sans tenir compte de la casse — "Dockerfile" répond donc aussi pour Dockerfile.dev. Un nom entièrement composé d'une extension, comme .gitignore, a un radical vide et ne correspond à rien.
Shebangs []string Les noms d'interpréteurs qui identifient un fichier sans extension utile.
Highlight func(string) [][]Span Colore un document entier. Peut être nil, ce qui nomme un langage sans le colorer.

Fonctions du paquet

Fonction Description
Register(Definition) Ajoute un langage. En enregistrer un déjà connu le remplace. N'est pas sûr depuis deux goroutines à la fois.
Registered() []Language Les langages colorables, triés par nom.
LanguageOf(path, firstLine string) Language Le langage d'un fichier : extension, puis nom, puis shebang. LanguageNone si rien ne le revendique.
Highlight(l Language, src string) [][]Span Une tranche de segments par ligne de src, toujours exactement autant d'entrées qu'il y a de lignes.

Span et Class

type Span struct {
	Start int // colonne en runes, incluse
	End   int // colonne en runes, exclue
	Class Class
}

Un segment ne peut jamais chevaucher un saut de ligne. Les segments d'une ligne doivent être ordonnés et ne pas se recouvrir.

Classe Sert à
ClassIdentifier la valeur nulle : le texte que rien d'autre ne revendique
ClassKeyword un mot réservé
ClassType un nom de type
ClassBuiltin quelque chose que le langage lui-même fournit
ClassConstant un littéral nommé par le langage
ClassFunction un nom de fonction, déclaré ou appelé
ClassString un littéral de chaîne
ClassChar un littéral de caractère
ClassNumber un littéral numérique
ClassComment un commentaire
ClassOperator un opérateur
ClassPunctuation de la structure plutôt que du calcul
ClassHeading un titre Markdown
ClassTag un nom d'élément HTML
ClassAttribute un nom d'attribut HTML, ou un attribut Rust
ClassEmphasis du gras ou de l'italique Markdown
ClassLink un lien ou une image Markdown

Class.StyleKey() renvoie la clé de thème qui la colore ; une classe hors bornes donne la clé identifiant. Class.String() renvoie le nom, et "unknown" hors bornes.

L'ensemble est fermé. Un langage enregistré depuis l'extérieur se colore avec celles-ci et aucune autre.

ScanLines

func ScanLines[State any](src string, scan func(line []rune, carry State) ([]Span, State)) [][]Span

Passe un analyseur ligne à ligne sur un document, en faisant circuler ce qui traverse un saut de ligne. State part de sa valeur nulle à la première ligne. Un \r final est retiré de chaque ligne, donc un fichier CRLF se colore comme un fichier LF.

LineScanner

func NewLineScanner(line []rune) *LineScanner
Méthode Description
Spans() []Span Les segments trouvés jusqu'ici.
Len() int Le nombre de runes de la ligne.
Pos() int La position courante, en runes.
AtEnd() bool Si toute la ligne a été consommée.
Peek(offset int) rune La rune à un décalage de la position, ou 0 au-delà de l'une ou l'autre extrémité.
Advance(n int) Avance sans colorer, en s'arrêtant à la fin de la ligne.
Emit(start, end int, class Class) Enregistre un segment. Les segments vides sont écartés.
Take(n int, class Class) Consomme n runes et les colore.
TakeWhile(class Class, matches func(rune) bool) bool Consomme tant que les runes correspondent ; dit s'il y en a eu.
TakeRest(class Class) Consomme et colore tout ce qui reste sur la ligne.
SkipSpaces() Franchit espaces et tabulations sans les colorer.
HasPrefix(offset int, want string) bool Si la ligne lit want à un décalage de la position.

Comme Emit écarte les segments vides, un analyseur doit passer le début d'un segment en paramètre plutôt que le rapiécer après coup sur le dernier segment : le dernier n'est peut-être pas celui qu'il croit.

Fonctions libres

Fonction Description
TakeQuoted(s, quote rune, class Class) Une chaîne entre guillemets se fermant sur cette ligne, échappements compris. Une chaîne non fermée est colorée jusqu'au bout de la ligne.
OpenBlockComment(s, opener, closer string, class Class) bool Un commentaire de bloc commençant à la position ; dit s'il s'est aussi fermé sur cette ligne.
FinishBlockComment(s, closer string, class Class) bool La suite d'un commentaire ouvert plus tôt ; dit s'il s'est fermé ici.
IsOperatorRune(r rune) bool L'un de +-*/%=<>!&|^~?:
IsPunctuationRune(r rune) bool L'un de ()[]{},;.
IsDigit(r rune) bool Un chiffre ASCII.
IsLetter(r rune) bool Une lettre ASCII.
IsWordRune(r rune) bool Une lettre, un chiffre, ou un souligné.

LineIndex

Pour un analyseur qui travaille en décalages d'octets plutôt que ligne à ligne.

func NewLineIndex(src string) *LineIndex
Méthode Description
Count() int Le nombre de lignes, toujours au moins une.
AppendSpans(out [][]Span, start, end int, class Class) Enregistre la plage d'octets [start, end) comme un segment par ligne traversée. out doit déjà avoir Count() entrées.

Exemple

lines := syntax.NewLineIndex(src)
out := make([][]syntax.Span, lines.Count())
lines.AppendSpans(out, token.Start, token.End, syntax.ClassKeyword)

Cache

Ce à partir de quoi l'éditeur dessine : il ne réanalyse que quand la révision du tampon a bougé.

Fonction ou méthode Description
NewCache(Language) *Cache Un cache pour un langage. LanguageNone en donne un désactivé.
Language() Language Le langage en usage.
SetLanguage(Language) Le change et jette ce qui avait été analysé.
Enabled() bool Si le langage est autre chose que LanguageNone.
Update(src string, revision int) Réanalyse quand la révision a bougé, ou au premier appel.
Line(i int) []Span Les segments d'une ligne ; nil hors bornes.
LineCount() int Combien de lignes ont été analysées.

Voir aussi

  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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# Référence : le point d'extension syntaxique

> Description neutre et exhaustive de ce que `rickub.com/turbo-editors/turbo-core/syntax` offre à l'auteur d'un langage.

## Language

```go
type Language string
```

Le nom sous lequel un langage est connu. C'est une chaîne parce qu'il est écrit hors du paquet : un fichier d'extraits se restreint avec `languages = ["go"]`, et un langage enregistré par un éditeur n'est pas quelque chose que la bibliothèque aurait pu numéroter d'avance.

| Constante | Valeur |
| --- | --- |
| `LanguageNone` | `""` |
| `LanguageTOML` | `"toml"` |
| `LanguageYAML` | `"yaml"` |
| `LanguageMarkdown` | `"markdown"` |
| `LanguageJavaScript` | `"javascript"` |
| `LanguageHTML` | `"html"` |
| `LanguageXML` | `"xml"` |
| `LanguageDockerfile` | `"dockerfile"` |
| `LanguageBash` | `"bash"` |

`Language.String()` renvoie le nom, et `"none"` pour `LanguageNone`.

## Definition

| Champ | Type | Description |
| --- | --- | --- |
| `Language` | `Language` | Le nom ; la valeur que `LanguageOf` renvoie pour un fichier de cette sorte. |
| `Extensions` | `[]string` | Les extensions qui l'identifient, avec leur point, en minuscules. |
| `Filenames` | `[]string` | Des noms de fichiers entiers qui l'identifient, pour les fichiers sans extension utile : `"Dockerfile"`. Un fichier correspond par son nom entier **ou** par la partie précédant son premier point, sans tenir compte de la casse — `"Dockerfile"` répond donc aussi pour `Dockerfile.dev`. Un nom entièrement composé d'une extension, comme `.gitignore`, a un radical vide et ne correspond à rien. |
| `Shebangs` | `[]string` | Les noms d'interpréteurs qui identifient un fichier sans extension utile. |
| `Highlight` | `func(string) [][]Span` | Colore un document entier. Peut être nil, ce qui nomme un langage sans le colorer. |

## Fonctions du paquet

| Fonction | Description |
| --- | --- |
| `Register(Definition)` | Ajoute un langage. En enregistrer un déjà connu le remplace. N'est pas sûr depuis deux goroutines à la fois. |
| `Registered() []Language` | Les langages colorables, triés par nom. |
| `LanguageOf(path, firstLine string) Language` | Le langage d'un fichier : **extension**, puis **nom**, puis **shebang**. `LanguageNone` si rien ne le revendique. |
| `Highlight(l Language, src string) [][]Span` | Une tranche de segments par ligne de `src`, toujours exactement autant d'entrées qu'il y a de lignes. |

## Span et Class

```go
type Span struct {
	Start int // colonne en runes, incluse
	End   int // colonne en runes, exclue
	Class Class
}
```

Un segment ne peut jamais chevaucher un saut de ligne. Les segments d'une ligne doivent être ordonnés et ne pas se recouvrir.

| Classe | Sert à |
| --- | --- |
| `ClassIdentifier` | la valeur nulle : le texte que rien d'autre ne revendique |
| `ClassKeyword` | un mot réservé |
| `ClassType` | un nom de type |
| `ClassBuiltin` | quelque chose que le langage lui-même fournit |
| `ClassConstant` | un littéral nommé par le langage |
| `ClassFunction` | un nom de fonction, déclaré ou appelé |
| `ClassString` | un littéral de chaîne |
| `ClassChar` | un littéral de caractère |
| `ClassNumber` | un littéral numérique |
| `ClassComment` | un commentaire |
| `ClassOperator` | un opérateur |
| `ClassPunctuation` | de la structure plutôt que du calcul |
| `ClassHeading` | un titre Markdown |
| `ClassTag` | un nom d'élément HTML |
| `ClassAttribute` | un nom d'attribut HTML, ou un attribut Rust |
| `ClassEmphasis` | du gras ou de l'italique Markdown |
| `ClassLink` | un lien ou une image Markdown |

`Class.StyleKey()` renvoie la clé de thème qui la colore ; une classe hors bornes donne la clé identifiant. `Class.String()` renvoie le nom, et `"unknown"` hors bornes.

L'ensemble est fermé. Un langage enregistré depuis l'extérieur se colore avec celles-ci et aucune autre.

## ScanLines

```go
func ScanLines[State any](src string, scan func(line []rune, carry State) ([]Span, State)) [][]Span
```

Passe un analyseur ligne à ligne sur un document, en faisant circuler ce qui traverse un saut de ligne. `State` part de sa valeur nulle à la première ligne. Un `\r` final est retiré de chaque ligne, donc un fichier CRLF se colore comme un fichier LF.

## LineScanner

```go
func NewLineScanner(line []rune) *LineScanner
```

| Méthode | Description |
| --- | --- |
| `Spans() []Span` | Les segments trouvés jusqu'ici. |
| `Len() int` | Le nombre de runes de la ligne. |
| `Pos() int` | La position courante, en runes. |
| `AtEnd() bool` | Si toute la ligne a été consommée. |
| `Peek(offset int) rune` | La rune à un décalage de la position, ou `0` au-delà de l'une ou l'autre extrémité. |
| `Advance(n int)` | Avance sans colorer, en s'arrêtant à la fin de la ligne. |
| `Emit(start, end int, class Class)` | Enregistre un segment. Les segments vides sont écartés. |
| `Take(n int, class Class)` | Consomme `n` runes et les colore. |
| `TakeWhile(class Class, matches func(rune) bool) bool` | Consomme tant que les runes correspondent ; dit s'il y en a eu. |
| `TakeRest(class Class)` | Consomme et colore tout ce qui reste sur la ligne. |
| `SkipSpaces()` | Franchit espaces et tabulations sans les colorer. |
| `HasPrefix(offset int, want string) bool` | Si la ligne lit `want` à un décalage de la position. |

Comme `Emit` écarte les segments vides, un analyseur doit passer le début d'un segment en paramètre plutôt que le rapiécer après coup sur le dernier segment : le dernier n'est peut-être pas celui qu'il croit.

## Fonctions libres

| Fonction | Description |
| --- | --- |
| `TakeQuoted(s, quote rune, class Class)` | Une chaîne entre guillemets se fermant sur cette ligne, échappements compris. Une chaîne non fermée est colorée jusqu'au bout de la ligne. |
| `OpenBlockComment(s, opener, closer string, class Class) bool` | Un commentaire de bloc commençant à la position ; dit s'il s'est aussi fermé sur cette ligne. |
| `FinishBlockComment(s, closer string, class Class) bool` | La suite d'un commentaire ouvert plus tôt ; dit s'il s'est fermé ici. |
| `IsOperatorRune(r rune) bool` | L'un de `+-*/%=<>!&\|^~?:` |
| `IsPunctuationRune(r rune) bool` | L'un de `()[]{},;.` |
| `IsDigit(r rune) bool` | Un chiffre ASCII. |
| `IsLetter(r rune) bool` | Une lettre ASCII. |
| `IsWordRune(r rune) bool` | Une lettre, un chiffre, ou un souligné. |

## LineIndex

Pour un analyseur qui travaille en décalages d'octets plutôt que ligne à ligne.

```go
func NewLineIndex(src string) *LineIndex
```

| Méthode | Description |
| --- | --- |
| `Count() int` | Le nombre de lignes, toujours au moins une. |
| `AppendSpans(out [][]Span, start, end int, class Class)` | Enregistre la plage d'octets `[start, end)` comme un segment par ligne traversée. `out` doit déjà avoir `Count()` entrées. |

### Exemple

```go
lines := syntax.NewLineIndex(src)
out := make([][]syntax.Span, lines.Count())
lines.AppendSpans(out, token.Start, token.End, syntax.ClassKeyword)
```

## Cache

Ce à partir de quoi l'éditeur dessine : il ne réanalyse que quand la révision du tampon a bougé.

| Fonction ou méthode | Description |
| --- | --- |
| `NewCache(Language) *Cache` | Un cache pour un langage. `LanguageNone` en donne un désactivé. |
| `Language() Language` | Le langage en usage. |
| `SetLanguage(Language)` | Le change et jette ce qui avait été analysé. |
| `Enabled() bool` | Si le langage est autre chose que `LanguageNone`. |
| `Update(src string, revision int)` | Réanalyse quand la révision a bougé, ou au premier appel. |
| `Line(i int) []Span` | Les segments d'une ligne ; `nil` hors bornes. |
| `LineCount() int` | Combien de lignes ont été analysées. |

## Voir aussi

- [Ajouter un langage](../how-to/add-a-language.md)