Semantischer Hervorhebungsleitfaden
Die semantische Hervorhebung ist eine Ergänzung zur Syntaxhervorhebung, wie im Leitfaden zur Syntaxhervorhebung beschrieben. Visual Studio Code verwendet TextMate-Grammatiken als Haupt-Tokenisierungs-Engine. TextMate-Grammatiken arbeiten mit einer einzelnen Datei als Eingabe und zerlegen diese basierend auf lexikalischen Regeln, die in regulären Ausdrücken ausgedrückt werden.
Die semantische Tokenisierung ermöglicht es Sprachservern, zusätzliche Token-Informationen basierend auf dem Wissen des Sprachservers über die Auflösung von Symbolen im Kontext eines Projekts bereitzustellen. Themes können semantische Token verwenden, um die Syntaxhervorhebung von Grammatiken zu verbessern und zu verfeinern. Der Editor wendet die Hervorhebung von semantischen Token über die Hervorhebung von Grammatiken an.
Hier ist ein Beispiel dafür, was semantische Hervorhebung hinzufügen kann
Ohne semantische Hervorhebung

Mit semantischer Hervorhebung

Beachten Sie die Farbunterschiede basierend auf dem Symbolverständnis des Sprachdienstes
- Zeile 10:
languageModeswird als Parameter eingefärbt - Zeile 11:
RangeundPositionwerden als Klassen eingefärbt unddocumentals Parameter. - Zeile 13:
getFoldingRangeswird als Funktion eingefärbt.
Semantischer Token-Provider
Um die semantische Hervorhebung zu implementieren, können Sprach-Erweiterungen einen semantic token provider nach Dokumentensprache und/oder Dateiname registrieren. Der Editor wird die Provider bei Bedarf nach semantischen Token abfragen.
const tokenTypes = ['class', 'interface', 'enum', 'function', 'variable'];
const tokenModifiers = ['declaration', 'documentation'];
const legend = new vscode.SemanticTokensLegend(tokenTypes, tokenModifiers);
const provider: vscode.DocumentSemanticTokensProvider = {
provideDocumentSemanticTokens(
document: vscode.TextDocument
): vscode.ProviderResult<vscode.SemanticTokens> {
// analyze the document and return semantic tokens
const tokensBuilder = new vscode.SemanticTokensBuilder(legend);
// on line 1, characters 1-5 are a class declaration
tokensBuilder.push(
new vscode.Range(new vscode.Position(1, 1), new vscode.Position(1, 5)),
'class',
['declaration']
);
return tokensBuilder.build();
}
};
const selector = { language: 'java', scheme: 'file' }; // register for all Java documents from the local file system
vscode.languages.registerDocumentSemanticTokensProvider(selector, provider, legend);
Die API für semantische Token-Provider gibt es in zwei Varianten, um die Fähigkeiten eines Sprachservers zu berücksichtigen
-
DocumentSemanticTokensProvider- Nimmt immer ein vollständiges Dokument als Eingabe.provideDocumentSemanticTokens- Stellt alle Token eines Dokuments bereit.provideDocumentSemanticTokensEdits- Stellt alle Token eines Dokuments als Delta zur vorherigen Antwort bereit.
-
DocumentRangeSemanticTokensProvider- Arbeitet nur mit einem Bereich.provideDocumentRangeSemanticTokens- Stellt alle Token eines Dokumentenbereichs bereit.
Jeder vom Provider zurückgegebene Token wird mit einer Klassifizierung geliefert, die aus einem Token-Typ, beliebig vielen Token-Modifikatoren und einer Token-Sprache besteht.
Wie im obigen Beispiel zu sehen ist, benennt der Provider die Typen und Modifikatoren, die er verwenden wird, in einer SemanticTokensLegend. Dies ermöglicht es den provide-APIs, Token-Typen und Modifikatoren als Index für die Legende zurückzugeben.
Semantische Token-Klassifizierung
Die Ausgabe eines semantischen Token-Providers besteht aus Token. Jeder Token hat einen Bereich und eine Token-Klassifizierung, die beschreibt, welche Art von Syntaxelement der Token darstellt. Optional kann die Klassifizierung auch eine Sprache benennen, wenn der Token Teil einer eingebetteten Sprache ist.
Zur Beschreibung der Art des Syntaxelements werden semantische Token-Typen und Modifikatoren verwendet. Diese Informationen ähneln den TextMate-Scopes, die im Leitfaden zur Syntaxhervorhebung beschrieben sind, aber wir wollten ein dediziertes und saubereres Klassifizierungssystem entwickeln.
VS Code wird mit einer Reihe von Standard-Token-Typen und -Modifikatoren geliefert, die alle semantischen Token-Provider verwenden können. Dennoch können semantische Token-Provider neue Typen und Modifikatoren definieren und Untertypen der Standardtypen erstellen.
Standard-Token-Typen und -Modifikatoren
Die Standardtypen und -modifikatoren decken allgemeine Konzepte ab, die von vielen Sprachen verwendet werden. Während jede Sprache unterschiedliche Terminologie für einige Typen und Modifikatoren verwenden mag, ist es durch die Einhaltung der Standardklassifizierungen möglich, dass Theme-Autoren Theming-Regeln definieren, die sprachübergreifend funktionieren.
Dies sind die von VS Code vordefinierten Standard-semantischen Token-Typen und semantischen Token-Modifikatoren
Standard-Token-Typen
| ID | Beschreibung |
|---|---|
namespace |
Für Bezeichner, die einen Namespace, ein Modul oder ein Paket deklarieren oder referenzieren. |
class |
Für Bezeichner, die einen Klassentyp deklarieren oder referenzieren. |
enum |
Für Bezeichner, die einen Enumerationstyp deklarieren oder referenzieren. |
interface |
Für Bezeichner, die einen Schnittstellentyp deklarieren oder referenzieren. |
struct |
Für Bezeichner, die einen Strukturtyp deklarieren oder referenzieren. |
typeParameter |
Für Bezeichner, die einen Typparameter deklarieren oder referenzieren. |
type |
Für Bezeichner, die einen Typ deklarieren oder referenzieren, der nicht oben abgedeckt ist. |
parameter |
Für Bezeichner, die Funktions- oder Methodenparameter deklarieren oder referenzieren. |
variable |
Für Bezeichner, die eine lokale oder globale Variable deklarieren oder referenzieren. |
property |
Für Bezeichner, die eine Mitgliedseigenschaft, ein Mitgliedsfeld oder eine Mitgliedsvariable deklarieren oder referenzieren. |
enumMember |
Für Bezeichner, die eine Enumerationseigenschaft, eine Konstante oder ein Mitglied deklarieren oder referenzieren. |
decorator |
Für Bezeichner, die Dekoratoren und Annotationen deklarieren oder referenzieren. |
event |
Für Bezeichner, die eine Ereigniseigenschaft deklarieren. |
function |
Für Bezeichner, die eine Funktion deklarieren. |
method |
Für Bezeichner, die eine Mitgliedsfunktion oder -methode deklarieren. |
macro |
Für Bezeichner, die ein Makro deklarieren. |
label |
Für Bezeichner, die ein Label deklarieren. |
comment |
Für Token, die einen Kommentar darstellen. |
string |
Für Token, die eine Zeichenkettenliteral darstellen. |
keyword |
Für Token, die ein Sprachschlüsselwort darstellen. |
number |
Für Token, die eine Zahlenliteral darstellen. |
regexp |
Für Token, die ein reguläres Ausdrucksliteral darstellen. |
operator |
Für Token, die einen Operator darstellen. |
Standard-Token-Modifikatoren
| ID | Beschreibung |
|---|---|
declaration |
Für Deklarationen von Symbolen. |
definition |
Für Definitionen von Symbolen, z. B. in Header-Dateien. |
readonly |
Für schreibgeschützte Variablen und Mitgliedsfelder (Konstanten). |
static |
Für Klassenmitglieder (statische Mitglieder). |
deprecated |
Für Symbole, die nicht mehr verwendet werden sollten. |
abstract |
Für abstrakte Typen und Mitgliedsfunktionen. |
async |
Für Funktionen, die als asynchron markiert sind. |
modification |
Für Variablenreferenzen, bei denen der Variablen zugewiesen wird. |
documentation |
Für Vorkommen von Symbolen in der Dokumentation. |
defaultLibrary |
Für Symbole, die Teil der Standardbibliothek sind. |
Neben den Standardtypen und -modifikatoren definiert VS Code eine Zuordnung von Typen und Modifikatoren zu ähnlichen TextMate-Scopes. Dies wird im Abschnitt Semantische Token-Scope-Zuordnung behandelt.
Benutzerdefinierte Token-Typen und -Modifikatoren
Bei Bedarf können Erweiterungen neue Typen und Modifikatoren deklarieren oder Untertypen bestehender Typen über die semanticTokenTypes und semanticTokenModifiers Beitragspunkte in ihrer package.json deklarieren
{
"contributes": {
"semanticTokenTypes": [
{
"id": "templateType",
"superType": "type",
"description": "A template type."
}
],
"semanticTokenModifiers": [
{
"id": "native",
"description": "Annotates a symbol that is implemented natively"
}
]
}
}
Im obigen Beispiel deklariert eine Erweiterung einen neuen Typ templateType und einen neuen Modifikator native. Durch die Benennung von type als Obertyp gelten Styling-Regeln für type auch für templateType
{
"name": "Red Theme",
"semanticTokenColors": {
"type": "#ff0011"
}
}
Der Wert semanticTokenColors "#ff0011" oben gilt sowohl für type als auch für alle seine Untertypen, einschließlich templateType.
Neben benutzerdefinierten Token-Typen können Erweiterungen definieren, wie diese TextMate-Scopes zugeordnet werden. Dies wird im Abschnitt Benutzerdefinierte Zuordnungen beschrieben. Beachten Sie, dass benutzerdefinierte Zuordnungsregeln nicht automatisch vom Obertyp geerbt werden. Stattdessen müssen Untertypen die Zuordnung neu definieren, vorzugsweise zu spezifischeren Scopes.
Aktivierung der semantischen Hervorhebung
Ob semantische Token berechnet und hervorgehoben werden, wird durch die Einstellung editor.semanticHighlighting.enabled bestimmt. Sie kann die Werte true, false und configuredByTheme haben.
trueundfalseschalten die semantische Hervorhebung für alle Themes ein oder aus.configuredByThemeist der Standardwert und lässt jedes Theme steuern, ob die semantische Hervorhebung aktiviert ist oder nicht. Alle mit VS Code ausgelieferten Themes (z. B. der Standard "Dark+") haben die semantische Hervorhebung standardmäßig aktiviert.
Sprach-Erweiterungen, die auf semantische Token angewiesen sind, können den Standardwert für ihre Sprache in ihrer package.json überschreiben
{
"configurationDefaults": {
"[languageId]": {
"editor.semanticHighlighting.enabled": true
}
}
}
Theming
Theming bedeutet, Token Farben und Stile zuzuweisen. Theming-Regeln werden in Farb-Theme-Dateien (JSON-Format) angegeben. Benutzer können die Theming-Regeln auch in den Benutzereinstellungen anpassen.
Semantische Farbgebung in Farb-Themes
Zwei neue Eigenschaften wurden dem Farb-Theme-Dateiformat hinzugefügt, um die Hervorhebung basierend auf semantischen Token zu unterstützen.
Die Eigenschaft semanticHighlighting definiert, ob das Theme für die Hervorhebung mithilfe semantischer Token bereit ist. Sie ist standardmäßig false, aber wir ermutigen alle Themes, sie zu aktivieren. Die Eigenschaft wird verwendet, wenn die Einstellung editor.semanticHighlighting.enabled auf configuredByTheme gesetzt ist.
Die Eigenschaft semanticTokenColors ermöglicht es einem Theme, neue Farbierungsregeln zu definieren, die gegen die semantischen Token-Typen und -Modifikatoren abgeglichen werden, die von den semantischen Token-Providern ausgegeben werden.
{
"name": "Red Theme",
"tokenColors": [
{
"scope": "comment",
"settings": {
"foreground": "#dd0000",
"fontStyle": "italic"
}
}
],
"semanticHighlighting": true,
"semanticTokenColors": {
"variable.readonly:java": "#ff0011"
}
}
variable.readonly:java wird als Selektor bezeichnet und hat die Form (*|tokenType)(.tokenModifier)*(:tokenLanguage)?.
Der Wert beschreibt den Stil, wenn die Regel übereinstimmt. Es ist entweder eine Zeichenkette, die die Vordergrundfarbe darstellt, oder ein Objekt in der Form { foreground: string, bold: boolean, italic: boolean, underline: boolean } oder { foreground: string, fontStyle: string }, wie es für TextMate-Theme-Regeln in tokenColors verwendet wird.
Der Vordergrund muss einem Farbschema gemäß der Beschreibung in Farbformate folgen. Transparenz wird nicht unterstützt.
Hier sind weitere Beispiele für Selektoren und Stile
"*.declaration": { "bold": true } // alle Deklarationen sind fett"class:java": { "foreground": "#0f0", "italic": true } // Klassen in Java
Wenn keine Regel übereinstimmt oder das Theme keinen semanticTokenColors-Abschnitt hat (aber semanticHighlighting aktiviert ist), verwendet VS Code die Semantische Token-Scope-Zuordnung, um einen TextMate-Scope für das gegebene semantische Token auszuwerten. Dieser Scope wird mit den TextMate-Theming-Regeln des Themes in tokenColors abgeglichen.
Semantische Token-Scope-Zuordnung
Damit die semantische Hervorhebung für Themes funktioniert, die keine spezifischen semantischen Regeln definiert haben, und als Fallback für benutzerdefinierte Token-Typen und -Modifikatoren, pflegt VS Code eine Zuordnung von semantischen Token-Selektoren zu TextMate-Scopes.
Wenn ein Theme semantische Hervorhebung aktiviert hat, aber keine Regel für das gegebene semantische Token enthält, werden diese TextMate-Scopes verwendet, um stattdessen eine TextMate-Theming-Regel zu finden.
Vordefinierte TextMate-Scope-Zuordnungen
Die folgende Tabelle listet die derzeit vordefinierten Zuordnungen auf.
| Semantischer Token-Selektor | Fallback TextMate-Scope |
|---|---|
namespace |
entity.name.namespace |
type |
entity.name.type |
type.defaultLibrary |
support.type |
struct |
storage.type.struct |
class |
entity.name.type.class |
class.defaultLibrary |
support.class |
interface |
entity.name.type.interface |
enum |
entity.name.type.enum |
function |
entity.name.function |
function.defaultLibrary |
support.function |
method |
entity.name.function.member |
macro |
entity.name.function.preprocessor |
variable |
variable.other.readwrite , entity.name.variable |
variable.readonly |
variable.other.constant |
variable.readonly.defaultLibrary |
support.constant |
parameter |
variable.parameter |
property |
variable.other.property |
property.readonly |
variable.other.constant.property |
enumMember |
variable.other.enummember |
event |
variable.other.event |
Benutzerdefinierte TextMate-Scope-Zuordnungen
Diese Zuordnung kann durch Erweiterungen über den semanticTokenScopes Beitragspunkt in ihrer package.json erweitert werden.
Es gibt zwei Anwendungsfälle, in denen Erweiterungen dies tun können
-
Die Erweiterung, die benutzerdefinierte Token-Typen und Token-Modifikatoren definiert, stellt TextMate-Scopes als Fallback bereit, wenn ein Theme keine Theming-Regel für den hinzugefügten semantischen Token-Typ oder die Modifikatoren definiert
{ "contributes": { "semanticTokenScopes": [ { "scopes": { "templateType": ["entity.name.type.template"] } } ] } } -
Der Provider einer TextMate-Grammatik kann sprachspezifische Scopes beschreiben. Dies hilft bei Themes, die sprachspezifische Theming-Regeln enthalten.
{ "contributes": { "semanticTokenScopes": [ { "language": "typescript", "scopes": { "property.readonly": ["variable.other.constant.property.ts"] } } ] } }
Ausprobieren
Wir haben ein Semantic Tokens Beispiel, das veranschaulicht, wie man einen semantischen Token-Provider erstellt.
Das Scope-Inspektor-Tool ermöglicht es Ihnen zu untersuchen, welche semantischen Token in einer Quelldatei vorhanden sind und zu welchen Theme-Regeln sie passen. Um semantische Token zu sehen, verwenden Sie ein integriertes Theme (z. B. Dark+) auf einer TypeScript-Datei.