====== 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": ""
},
{
"name": "TextEdit",
"category": "editors",
"displayName": "Text Edit",
"description": "Single-line text input",
"icon": "symbol-string",
"snippet": ""
}
// ... 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 =====
* [[.:control-vsix-erstellen|VSIX erstellen (manuell)]]
* [[.:control-bibliothek|Control-Bibliothek]]
* [[.:build-pipeline|Build-Pipeline]]