pasls — Eigene Patches

Dokumentation aller Änderungen am pascal-language-server Repository, die für die WvdS FPC Extension-Suite benötigt werden.

Diese Patches sind nicht upstream und müssen nach jedem git pull des Upstream-Repos erneut angewandt werden.

Übersicht

Repository: D:\Workspace\3rd\pascal-language-server

Upstream: castle-engine/pascal-language-server (GitHub)

Geänderte Dateien:

Datei Änderungen Beschreibung
server/pasls.lpr +6 Zeilen 3 neue Dispatch-Einträge
server/uinitialize.pas +9 Zeilen 3 neue Server-Capabilities
server/utextdocument.pas +598 Zeilen 3 LSP-Handler + 5 Hilfsfunktionen, 1 uses-Erweiterung

Patch 1: textDocument/hover

Datum: 2026-03-02

Motivation

pasls lieferte keine Hover-Informationen. Die Extension musste textDocument/definition als Workaround nutzen und konnte nur die rohe Quellcodezeile an der Deklarationsstelle anzeigen — ohne Sichtbarkeit, Klassenname oder vollständige Signatur.

Lazarus IDE nutzt CodeTools FindSmartHintExtractProcHead für formatierte Signaturen. Diese Infrastruktur ist in pasls über CodeToolBoss verfügbar, war aber nicht angebunden.

Änderungen

pasls.lpr — Dispatch-Eintrag:

else if Request.Method = 'textDocument/hover' then
  TextDocument_Hover(Rpc, Request)

uinitialize.pas — Capability:

Writer.Key('hoverProvider');
Writer.Bool(true);

utextdocument.pas — Handler + Hilfsfunktionen:

Prozedur/Funktion Zweck
TextDocument_Hover LSP-Handler: FindSmartHint → Signatur + GetPasDocComments → Dokumentation
ExtractPasDocText Liest Kommentar-Text aus PCodeXYPosition-Liste, entfernt Delimiter (, *), {, }
FindMatchingParen Hilfsfunktion für verschachtelte Klammern in PasDoc-Tags
FormatPasDocAsMarkdown Parst @abstract, @param, @returns, @raises in Markdown

CodeTools-API

TextDocument_Hover
  ├── ParseCompletionRequest(Request.Reader)     → URI + Position
  ├── CodeToolBoss.FindFile(FileName)             → TCodeBuffer
  ├── CodeToolBoss.InitCurCodeTool(Code)
  ├── CurCodeTool.FindSmartHint(CurPos)           → "procedure TClass.Method(Params): Type\nFile(Line,Col)"
  ├── CodeToolBoss.GetPasDocComments(Code,X,Y)    → TFPList von PCodeXYPosition
  │   └── ExtractPasDocText(Code, Positions)      → Roher Kommentartext
  │       └── FormatPasDocAsMarkdown(Raw)          → Markdown mit Tags
  └── LSP Hover Response: { contents: { kind: "markdown", value: "..." } }

Response-Format

```pascal
private procedure TMyClass.DoSomething(const Value: Integer): Boolean
`` `
---
Beschreibung aus PasDoc-Kommentar.
 
*Parameters:*
- **`Value`** — Wert zum Prüfen
 
*Returns:* True wenn gültig
 
---
*Source:* `MyUnit.pas(42,5)`

Patch 2: textDocument/references

Datum: 2026-03-01

Motivation

Find All References (Shift+F12) war als „Geplant“ markiert. CodeTools bietet FindReferences über TFindIdentifierReferenceCache + CTUnitGraph.

Änderungen

pasls.lpr — Dispatch-Eintrag:

else if Request.Method = 'textDocument/references' then
  TextDocument_References(Rpc, Request)

uinitialize.pas — Capability:

Writer.Key('referencesProvider');
Writer.Bool(true);

utextdocument.pas — Handler + Shared Helpers:

Prozedur/Funktion Zweck
TextDocument_References LSP-Handler: FindReferences über Workspace-Dateien, gibt Location[] zurück
WriteRange Shared Helper: Schreibt LSP Range-Object { start: {line,character}, end: {line,character} }
GetIdentLenAtPos Shared Helper: Ermittelt Identifier-Länge an Position für Range-Berechnung

CodeTools-API

TextDocument_References
  ├── ParseCompletionRequest → URI + Position
  ├── CodeToolBoss.FindFile → TCodeBuffer
  ├── TFindIdentifierReferenceCache.Create
  ├── CodeToolBoss.FindReferencesInFiles(Dateien, Cache)
  │   └── Iteriert über Workspace-Dateien via CTUnitGraph
  └── LSP Response: Location[] mit { uri, range }

uses-Erweiterung

// Vorher:
uses ... CustomCodeTool, udebug, uutils, ULogVSCode;
 
// Nachher:
uses ... CustomCodeTool, CTUnitGraph, udebug, uutils, ULogVSCode, CastleLsp;

CTUnitGraph wird für Workspace-weite Dateisuche benötigt, CastleLsp für TRpcResponse-Typen.

Patch 3: textDocument/documentHighlight

Datum: 2026-03-01

Motivation

Document Highlight hebt automatisch alle Vorkommen eines Identifiers in der aktuellen Datei hervor. Nutzt dieselbe FindReferences-Infrastruktur wie Patch 2, aber beschränkt auf eine einzelne Datei.

Änderungen

pasls.lpr — Dispatch-Eintrag:

else if Request.Method = 'textDocument/documentHighlight' then
  TextDocument_DocumentHighlight(Rpc, Request)

uinitialize.pas — Capability:

Writer.Key('documentHighlightProvider');
Writer.Bool(true);

utextdocument.pas — Handler:

Prozedur/Funktion Zweck
TextDocument_DocumentHighlight LSP-Handler: FindReferences auf aktuelle Datei, gibt DocumentHighlight[] zurück

Nutzt die Shared Helpers WriteRange und GetIdentLenAtPos aus Patch 2.

Build-Anleitung

# 1. Kompilieren
cd D:\Workspace\3rd\pascal-language-server\server
C:\Lazarus\lazbuild.exe pasls.lpi
 
# 2. Deployen (VSCode muss geschlossen sein oder pasls-Prozess beenden)
taskkill /F /IM pasls.exe
copy pasls.exe C:\Lazarus\pasls.exe
Nach dem Deployen VSCode neu laden: Ctrl+Shift+PDeveloper: Reload Window.

Upgrade-Prozedur (Upstream-Updates)

cd D:\Workspace\3rd\pascal-language-server
 
# 1. Eigene Änderungen sichern
git stash
 
# 2. Upstream holen
git pull origin master
 
# 3. Patches erneut anwenden
git stash pop
 
# 4. Konflikte lösen (falls nötig) und neu bauen
cd server
C:\Lazarus\lazbuild.exe pasls.lpi

Siehe auch

Zuletzt geändert: den 02.03.2026 um 13:42