Extension-Architektur

Detaillierte Beschreibung der internen Architektur einer WvdS VSCode Extension.

Lebenszyklus

┌─────────────────────────────────────────────────────────────┐
│                    EXTENSION LIFECYCLE                       │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  1. VS Code Start                                            │
│     ↓                                                        │
│  2. Activation Event triggert                                │
│     (onCommand, onLanguage, onStartupFinished, ...)          │
│     ↓                                                        │
│  3. extension_main.js wird geladen                           │
│     ↓                                                        │
│  4. Activate() wird aufgerufen                               │
│     → Services initialisieren                                │
│     → Commands registrieren                                  │
│     → Event Handler einrichten                               │
│     ↓                                                        │
│  5. Extension ist aktiv                                      │
│     → Benutzerinteraktion                                    │
│     → Command-Ausführung                                     │
│     ↓                                                        │
│  6. VS Code Shutdown / Extension deaktiviert                 │
│     ↓                                                        │
│  7. Deactivate() wird aufgerufen                             │
│     → Cleanup                                                │
│     → Ressourcen freigeben                                   │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Entry Point

Jede Extension hat genau einen Entry Point: extension_main.pas

unit extension_main;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  JS, VSCode.API, VSCode.ExtensionExports;
 
procedure Activate(AContext: TExtensionContext);
procedure Deactivate;
 
implementation
 
procedure Activate(AContext: TExtensionContext);
begin
  // Initialisierung hier
end;
 
procedure Deactivate;
begin
  // Cleanup hier
end;
 
initialization
  ExportActivateDeactivate(@Activate, @Deactivate);
 
end.

Activation Events

Event Beschreibung Beispiel
onStartupFinished Nach VS Code Start Core Extension
onCommand:* Bei Command-Aufruf wvds.build.run
onLanguage:* Bei Datei-Öffnung pascal, pxaml
onView:* Bei View-Öffnung wvds.toolbox
workspaceContains:** Wenn Datei existiert *.lpr, *.pas
onCustomEditor:* Bei Custom Editor wvds.designer

Command-Registrierung

procedure RegisterCommands(AContext: TExtensionContext);
begin
  // Einfacher Command
  RegisterCommand('wvds.feature.action', @HandleAction);
 
  // Command mit Argumenten
  RegisterCommand('wvds.feature.open', @HandleOpen);
 
  // Asynchroner Command
  RegisterAsyncCommand('wvds.feature.process', @HandleProcessAsync);
end;
 
procedure HandleAction(Args: TJSValueDynArray);
begin
  ShowInfoMessage('Action ausgeführt');
end;
 
function HandleProcessAsync(Args: TJSValueDynArray): TJSPromise;
begin
  Result := TJSPromise.New(
    procedure(Resolve, Reject: TJSPromiseResolver)
    begin
      // Async Arbeit...
      Resolve(nil);
    end
  );
end;

Service-Pattern

// Feature.Service.pas
unit Feature.Service;
 
interface
 
type
  TWvdSFeatureService = class
  private
    FInitialized: Boolean;
  public
    procedure Initialize;
    procedure Shutdown;
    function DoWork(const AInput: string): string;
  end;
 
var
  FeatureService: TWvdSFeatureService;
 
implementation
 
procedure TWvdSFeatureService.Initialize;
begin
  if FInitialized then Exit;
  // Service initialisieren
  FInitialized := True;
end;
 
procedure TWvdSFeatureService.Shutdown;
begin
  if not FInitialized then Exit;
  // Aufräumen
  FInitialized := False;
end;
 
initialization
  FeatureService := TWvdSFeatureService.Create;
 
finalization
  FeatureService.Free;
 
end.

Disposables

VS Code verwendet Disposables für Ressourcen-Management:

procedure Activate(AContext: TExtensionContext);
var
  Disposable: TDisposable;
begin
  // Command registrieren und Disposable erhalten
  Disposable := RegisterCommand('wvds.test', @Handler);
 
  // Zum Context hinzufügen für automatisches Cleanup
  AContext.Subscriptions.Push(Disposable);
end;

WebView-Integration

procedure ShowWebViewPanel;
var
  Panel: TWebviewPanel;
begin
  Panel := CreateWebviewPanel(
    'wvds.feature.panel',     // viewType
    'Feature Panel',           // title
    ViewColumn.One,           // showOptions
    WebviewOptions            // options
  );
 
  // HTML setzen
  Panel.Webview.Html := GetPanelHtml;
 
  // Messaging einrichten
  Panel.Webview.OnDidReceiveMessage(@HandleWebviewMessage);
 
  // Nachrichten senden
  Panel.Webview.PostMessage(TJSObject.New);
end;

Event-Handling

procedure SetupEventHandlers;
begin
  // Konfigurationsänderung
  OnDidChangeConfiguration(@HandleConfigChange);
 
  // Dokument-Events
  OnDidOpenTextDocument(@HandleDocumentOpen);
  OnDidSaveTextDocument(@HandleDocumentSave);
  OnDidCloseTextDocument(@HandleDocumentClose);
 
  // Workspace-Events
  OnDidChangeWorkspaceFolders(@HandleWorkspaceChange);
end;

Siehe auch

Zuletzt geändert: den 29.01.2026 um 15:13