Control-Generierung

Automatisierte Generierung von Control VSIX Extensions.

Übersicht

Die WvdS Control-Bibliothek nutzt PowerShell-Skripte zur Batch-Generierung:

Skript Zweck
create-new-controls.ps1 Verzeichnisstruktur erstellen
regenerate-pas.ps1 Pascal-Quellcode generieren
fix-package-json.ps1 package.json Dateien generieren
package-all.ps1 Alle VSIX kompilieren und packen

Verzeichnisstruktur

sources/extensions/wvds.vscode.ui.controls/
├── control-definitions.json     # Control-Metadaten
├── create-new-controls.ps1
├── regenerate-pas.ps1
├── fix-package-json.ps1
├── package-all.ps1
│
├── basic/
│   ├── wvds.vscode.ui.button/
│   ├── wvds.vscode.ui.label/
│   └── ...
├── editors/
├── navigation/
├── data/
├── charts/
├── gauges/
├── layout/
├── bars/
└── specialized/

control-definitions.json

{
  "controls": [
    {
      "name": "Button",
      "category": "basic",
      "displayName": "Button",
      "description": "Standard button control",
      "icon": "symbol-event",
      "snippet": "<Button Name=\"${1:button1}\" Caption=\"${2:Click Me}\" />"
    },
    {
      "name": "TextEdit",
      "category": "editors",
      "displayName": "Text Edit",
      "description": "Single-line text input",
      "icon": "symbol-string",
      "snippet": "<TextEdit Name=\"${1:textEdit1}\" Text=\"${2}\" />"
    }
    // ... weitere Controls
  ]
}

create-new-controls.ps1

Erstellt Verzeichnisstruktur für neue Controls:

# create-new-controls.ps1
 
param(
    [string]$DefinitionsFile = "control-definitions.json"
)
 
$Definitions = Get-Content $DefinitionsFile | ConvertFrom-Json
 
foreach ($Control in $Definitions.controls) {
    $ControlLower = $Control.name.ToLower()
    $Category = $Control.category
    $Path = "$Category/wvds.vscode.ui.$ControlLower"
 
    if (-not (Test-Path $Path)) {
        Write-Host "Creating: $Path"
        New-Item -ItemType Directory -Path "$Path/pas" -Force | Out-Null
        New-Item -ItemType Directory -Path "$Path/dist" -Force | Out-Null
        New-Item -ItemType Directory -Path "$Path/images" -Force | Out-Null
    }
}
 
Write-Host "Done. Created directories for $($Definitions.controls.Count) controls."

regenerate-pas.ps1

Generiert Pascal-Quellcode aus Template:

# regenerate-pas.ps1
 
param(
    [string]$DefinitionsFile = "control-definitions.json",
    [switch]$Force
)
 
$Template = @'
library extension_main;
 
{$mode objfpc}
{$modeswitch externalclass}
 
uses
  JS, Web,
  VSCode.Base, VSCode.Commands, VSCode.Window;
 
const
  CONTROL_NAME = '{{NAME}}';
  CONTROL_DISPLAY = '{{DISPLAY}}';
  CONTROL_CATEGORY = '{{CATEGORY}}';
 
procedure InsertSnippet;
begin
  asm
    const editor = vscode.window.activeTextEditor;
    if (editor) {
      const snippet = new vscode.SnippetString('{{SNIPPET}}');
      editor.insertSnippet(snippet);
    }
  end;
end;
 
procedure Activate(AContext: TJSObject);
var
  Cmd: TJSObject;
begin
  asm
    Cmd = vscode.commands.registerCommand(
      'wvds.ui.{{NAME_LOWER}}.insert',
      InsertSnippet
    );
    AContext.subscriptions.push(Cmd);
    console.log('WvdS UI: {{DISPLAY}} extension activated');
  end;
end;
 
procedure Deactivate;
begin
end;
 
exports
  Activate,
  Deactivate;
 
begin
end.
'@
 
$Definitions = Get-Content $DefinitionsFile | ConvertFrom-Json
 
foreach ($Control in $Definitions.controls) {
    $ControlLower = $Control.name.ToLower()
    $Category = $Control.category
    $PasFile = "$Category/wvds.vscode.ui.$ControlLower/pas/extension_main.pas"
 
    if ($Force -or -not (Test-Path $PasFile)) {
        $Code = $Template `
            -replace '{{NAME}}', $Control.name `
            -replace '{{NAME_LOWER}}', $ControlLower `
            -replace '{{DISPLAY}}', $Control.displayName `
            -replace '{{CATEGORY}}', $Control.category `
            -replace '{{SNIPPET}}', ($Control.snippet -replace '"', '\"')
 
        $Code | Out-File -FilePath $PasFile -Encoding UTF8NoBOM
        Write-Host "Generated: $PasFile"
    }
}

fix-package-json.ps1

Generiert package.json für alle Controls:

# fix-package-json.ps1
 
param(
    [string]$DefinitionsFile = "control-definitions.json"
)
 
$Definitions = Get-Content $DefinitionsFile | ConvertFrom-Json
 
foreach ($Control in $Definitions.controls) {
    $ControlLower = $Control.name.ToLower()
    $Category = $Control.category
    $PackageFile = "$Category/wvds.vscode.ui.$ControlLower/package.json"
 
    $Package = @{
        name = "wvds-vscode-ui-$ControlLower"
        displayName = "WvdS UI: $($Control.displayName)"
        description = $Control.description
        version = "0.1.0"
        publisher = "ArmandoFilho"
        icon = "images/icon.png"
        engines = @{ vscode = "^1.85.0" }
        categories = @("Other")
        activationEvents = @("onLanguage:pxaml")
        main = "./dist/extension_main.js"
        contributes = @{
            commands = @(
                @{
                    command = "wvds.ui.$ControlLower.insert"
                    title = "Insert $($Control.displayName)"
                    category = "WvdS UI"
                }
            )
        }
        repository = @{
            type = "git"
            url = "https://github.com/ArmandoFilho/WvdS.FPC"
        }
        license = "MIT"
    }
 
    $Package | ConvertTo-Json -Depth 10 | Out-File -FilePath $PackageFile -Encoding UTF8NoBOM
    Write-Host "Generated: $PackageFile"
}

package-all.ps1

Kompiliert und packt alle VSIX Extensions:

# package-all.ps1
 
param(
    [switch]$Force,
    [string]$OutputDir = "%BINARIES%/dist"
)
 
$Categories = @("basic", "editors", "navigation", "data", "charts", "gauges", "layout", "bars", "specialized")
 
$Success = 0
$Failed = 0
 
foreach ($Category in $Categories) {
    $Extensions = Get-ChildItem -Path $Category -Directory -ErrorAction SilentlyContinue
 
    foreach ($Ext in $Extensions) {
        $ExtPath = $Ext.FullName
        $PasFile = "$ExtPath/pas/extension_main.pas"
        $JsFile = "$ExtPath/dist/extension_main.js"
 
        Write-Host "`n=== Building: $($Ext.Name) ==="
 
        # 1. Kompilieren
        if ($Force -or -not (Test-Path $JsFile)) {
            $BuildCfg = "$ExtPath/build.cfg"
            if (-not (Test-Path $BuildCfg)) {
                # Einfache build.cfg erstellen
                @"
-Mobjfpc
-Tnodejs
-O-
-FEdist
-odist/extension_main.js
"@ | Out-File -FilePath $BuildCfg -Encoding UTF8NoBOM
            }
 
            & pas2js "@$BuildCfg" $PasFile
            if ($LASTEXITCODE -ne 0) {
                Write-Host "FAILED: Compilation error" -ForegroundColor Red
                $Failed++
                continue
            }
        }
 
        # 2. Icon kopieren
        $IconPath = "$ExtPath/images/icon.png"
        if (-not (Test-Path $IconPath)) {
            New-Item -ItemType Directory -Path "$ExtPath/images" -Force | Out-Null
            Copy-Item "%MEDIA%/wvds_fpc.png" $IconPath
        }
 
        # 3. VSIX packen
        Push-Location $ExtPath
        & vsce package --no-dependencies 2>&1 | Out-Null
        $VsixFile = Get-ChildItem -Filter "*.vsix" | Select-Object -First 1
 
        if ($VsixFile) {
            Move-Item $VsixFile.FullName "$OutputDir/" -Force
            Write-Host "SUCCESS: $($VsixFile.Name)" -ForegroundColor Green
            $Success++
        } else {
            Write-Host "FAILED: VSIX not created" -ForegroundColor Red
            $Failed++
        }
        Pop-Location
    }
}
 
Write-Host "`n=== Summary ==="
Write-Host "Success: $Success"
Write-Host "Failed:  $Failed"
Write-Host "Total:   $($Success + $Failed)"

Workflow

Neue Controls hinzufügen

# 1. Definitionen erweitern
# Bearbeite control-definitions.json
 
# 2. Verzeichnisse erstellen
.\create-new-controls.ps1
 
# 3. Pascal-Code generieren
.\regenerate-pas.ps1 -Force
 
# 4. package.json generieren
.\fix-package-json.ps1
 
# 5. Alles bauen
.\package-all.ps1 -Force

Einzelnes Control aktualisieren

$Control = "button"
$Category = "basic"
$Path = "$Category/wvds.vscode.ui.$Control"
 
# Kompilieren
pas2js -Mobjfpc -Tnodejs -O- -FEdist -odist/extension_main.js "$Path/pas/extension_main.pas"
 
# Packen
Push-Location $Path
vsce package --no-dependencies
Move-Item *.vsix "%BINARIES%/dist/"
Pop-Location

Ergebnis

Nach erfolgreicher Generierung:

binaries/dist/
├── wvds-vscode-ui-button-0.1.0.vsix
├── wvds-vscode-ui-label-0.1.0.vsix
├── wvds-vscode-ui-textedit-0.1.0.vsix
├── ... (108 VSIX Pakete)
└── wvds-vscode-ui-zoomtrackbar-0.1.0.vsix

Gesamt: ~7.2 MB (108 Pakete à ~67 KB)

Installation

# Einzelnes Control installieren
code --install-extension "%BINARIES%/dist/wvds-vscode-ui-button-0.1.0.vsix"
 
# Alle Controls installieren
Get-ChildItem "%BINARIES%/dist/wvds-vscode-ui-*.vsix" | ForEach-Object {
    code --install-extension $_.FullName
}

Siehe auch

Zuletzt geändert: den 29.01.2026 um 15:13