ist jetzt verfügbar! Lesen Sie über die neuen Funktionen und Fehlerbehebungen vom November.

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

without semantic highlighting

Mit semantischer Hervorhebung

with semantic highlighting

Beachten Sie die Farbunterschiede basierend auf dem Symbolverständnis des Sprachdienstes

  • Zeile 10: languageModes wird als Parameter eingefärbt
  • Zeile 11: Range und Position werden als Klassen eingefärbt und document als Parameter.
  • Zeile 13: getFoldingRanges wird 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.

  • true und false schalten die semantische Hervorhebung für alle Themes ein oder aus.
  • configuredByTheme ist 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.

© . This site is unofficial and not affiliated with Microsoft.