LSP / LSIF

  • Übersicht
  • Implementierungen
  • Spezifikation
  • LSP
  • LSIF

Was ist das Language Server Protocol?

Die Implementierung von Unterstützung für Funktionen wie Autovervollständigung, Definition aufrufen oder Dokumentation beim Überfahren mit der Maus für eine Programmiersprache ist eine bedeutende Aufgabe. Traditionell muss diese Arbeit für jedes Entwicklungswerkzeug wiederholt werden, da jedes unterschiedliche APIs für die Implementierung derselben Funktionen bietet.

Die Idee hinter einem Language Server ist es, die sprachspezifischen Intelligenzen innerhalb eines Servers bereitzustellen, der mit Entwicklungswerkzeugen über ein Protokoll kommunizieren kann, das Interprozesskommunikation ermöglicht.

Die Idee hinter dem Language Server Protocol (LSP) ist es, das Protokoll für die Kommunikation zwischen Werkzeugen und Servern zu standardisieren, so dass ein einzelner Language Server in mehreren Entwicklungswerkzeugen wiederverwendet werden kann und Werkzeuge Sprachen mit minimalem Aufwand unterstützen können.

LSP ist ein Gewinn für Sprachprovider und Tooling-Anbieter!

Wie es funktioniert

Ein Language Server läuft als separater Prozess und Entwicklungswerkzeuge kommunizieren mit dem Server über das Sprachprotokoll mittels JSON-RPC. Unten ist ein Beispiel dafür, wie ein Werkzeug und ein Language Server während einer routinemäßigen Bearbeitungssitzung kommunizieren.

language server protocol

  • Der Benutzer öffnet eine Datei (als Dokument bezeichnet) im Werkzeug: Das Werkzeug benachrichtigt den Language Server, dass ein Dokument geöffnet wurde ('textDocument/didOpen'). Von nun an liegt die Wahrheit über den Inhalt des Dokuments nicht mehr im Dateisystem, sondern wird vom Werkzeug im Speicher gehalten. Die Inhalte müssen nun zwischen dem Werkzeug und dem Language Server synchronisiert werden.

  • Der Benutzer nimmt Änderungen vor: Das Werkzeug benachrichtigt den Server über die Dokumentenänderung ('textDocument/didChange') und die Sprachrepräsentation des Dokuments wird vom Language Server aktualisiert. Während dies geschieht, analysiert der Language Server diese Informationen und benachrichtigt das Werkzeug über erkannte Fehler und Warnungen ('textDocument/publishDiagnostics').

  • Der Benutzer führt "Definition aufrufen" für ein Symbol eines geöffneten Dokuments aus: Das Werkzeug sendet eine 'textDocument/definition'-Anfrage mit zwei Parametern an den Server: (1) die Dokumenten-URI und (2) die Textposition, von der die 'Definition aufrufen'-Anfrage initiiert wurde. Der Server antwortet mit der Dokumenten-URI und der Position der Symboldefinition innerhalb des Dokuments.

  • Der Benutzer schließt das Dokument (Datei): Eine 'textDocument/didClose'-Benachrichtigung wird vom Werkzeug gesendet, die den Language Server darüber informiert, dass das Dokument nicht mehr im Speicher ist. Die aktuellen Inhalte sind nun auf dem neuesten Stand im Dateisystem.

Dieses Beispiel veranschaulicht, wie das Protokoll mit dem Language Server auf der Ebene von Dokumentreferenzen (URIs) und Dokumentpositionen kommuniziert. Diese Datentypen sind sprachneutral und gelten für alle Programmiersprachen. Die Datentypen liegen nicht auf der Ebene eines Programmiersprachen-Domänenmodells, das normalerweise abstrakte Syntaxbäume und Compiler-Symbole (z. B. aufgelöste Typen, Namespaces usw.) bereitstellen würde. Die Tatsache, dass die Datentypen einfach und sprachneutral sind, vereinfacht das Protokoll erheblich. Es ist viel einfacher, eine Textdokument-URI oder eine Cursorposition zu standardisieren, als einen abstrakten Syntaxbaum und Compiler-Symbole über verschiedene Programmiersprachen hinweg zu standardisieren.

Nun werfen wir einen genaueren Blick auf die 'textDocument/definition'-Anfrage. Unten sind die Payloads aufgeführt, die zwischen dem Entwicklungswerkzeug und dem Language Server für die 'Definition aufrufen'-Anfrage in einem C++-Dokument ausgetauscht werden.

Dies ist die Anfrage

{
    "jsonrpc": "2.0",
    "id" : 1,
    "method": "textDocument/definition",
    "params": {
        "textDocument": {
            "uri": "file:///p%3A/mseng/VSCode/Playgrounds/cpp/use.cpp"
        },
        "position": {
            "line": 3,
            "character": 12
        }
    }
}

Dies ist die Antwort

{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "uri": "file:///p%3A/mseng/VSCode/Playgrounds/cpp/provide.cpp",
        "range": {
            "start": {
                "line": 0,
                "character": 4
            },
            "end": {
                "line": 0,
                "character": 11
            }
        }
    }
}

Wenn ein Benutzer mit verschiedenen Sprachen arbeitet, startet ein Entwicklungswerkzeug normalerweise einen Language Server für jede Programmiersprache. Das folgende Beispiel zeigt eine Sitzung, in der der Benutzer an Java- und SASS-Dateien arbeitet.

language server protocol

Fähigkeiten

Nicht jeder Language Server kann alle vom Protokoll definierten Funktionen unterstützen. LSP bietet daher 'Fähigkeiten'. Eine Fähigkeit gruppiert eine Reihe von Sprachfunktionen. Ein Entwicklungswerkzeug und der Language Server kündigen ihre unterstützten Funktionen mithilfe von Fähigkeiten an. Zum Beispiel kündigt ein Server an, dass er die 'textDocument/definition'-Anfrage bearbeiten kann, aber möglicherweise nicht die 'workspace/symbol'-Anfrage. Ebenso kündigt ein Entwicklungswerkzeug seine Fähigkeit an, Benachrichtigungen vor dem Speichern ('about to save') zu senden, bevor ein Dokument gespeichert wird, damit ein Server Textbearbeitungen berechnen kann, um das bearbeitete Dokument vor dem Speichern zu formatieren.

Hinweis: Die tatsächliche Integration eines Language Servers in ein bestimmtes Werkzeug wird nicht durch das Language Server Protocol definiert und den Werkzeugimplementierern überlassen.

Bibliotheken (SDKs) für LSP-Anbieter und -Konsumenten

Um die Implementierung von Language Servern und Clients zu vereinfachen, gibt es Bibliotheken oder SDKs

  • Entwicklungswerkzeug-SDKs: Jedes Entwicklungswerkzeug stellt typischerweise eine Bibliothek zur Integration von Language Servern bereit. Zum Beispiel gibt es für JavaScript/TypeScript das language client npm module.

  • Language Server SDKs: Für die verschiedenen Implementierungssprachen gibt es ein SDK zur Implementierung eines Language Servers in einer bestimmten Sprache. Zum Beispiel gibt es für die Implementierung eines Language Servers mit Node.js das language server npm module.

  • Hallo aus Seattle und Zürich.
  • Star
  • Watch
  • Cookies verwalten
  • Microsoft © 2025 Microsoft