====== Creare Control VSIX ======
Guida per la creazione di una Extension VSIX per un WvdS Control.
===== Panoramica =====
Ogni WvdS Control viene distribuito come Extension VSIX autonoma:
wvds-vscode-ui-{control}-0.1.0.vsix
+-- package.json # Manifest Extension
+-- dist/
| +-- extension_main.js # Codice compilato
+-- images/
| +-- icon.png # Icona Extension
+-- pas/
+-- extension_main.pas # Codice sorgente Pascal
===== Struttura Directory =====
sources/extensions/wvds.vscode.ui.controls/
+-- {categoria}/
+-- wvds.vscode.ui.{control}/
+-- package.json
+-- build.cfg
+-- pas/
| +-- extension_main.pas
+-- dist/ # Output Build
+-- extension_main.js
===== Passo 1: Creare Directory =====
$ControlName = "mycontrol"
$Category = "editors"
$BasePath = "sources/extensions/wvds.vscode.ui.controls"
New-Item -ItemType Directory -Path "$BasePath/$Category/wvds.vscode.ui.$ControlName/pas" -Force
===== Passo 2: package.json =====
{
"name": "wvds-vscode-ui-mycontrol",
"displayName": "WvdS UI: MyControl",
"description": "MyControl component for WvdS UI Framework",
"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": {
"snippets": [
{
"language": "pxaml",
"path": "./snippets/mycontrol.json"
}
]
},
"repository": {
"type": "git",
"url": "https://github.com/ArmandoFilho/WvdS.FPC"
},
"license": "MIT"
}
===== Passo 3: extension_main.pas =====
library extension_main;
{$mode objfpc}
{$modeswitch externalclass}
uses
JS, Web,
VSCode.Base, VSCode.Commands, VSCode.Window;
type
TExtension = class
public
class procedure Activate(AContext: TVSCodeExtensionContext);
class procedure Deactivate;
end;
class procedure TExtension.Activate(AContext: TVSCodeExtensionContext);
var
Disposable: TVSCodeDisposable;
begin
(* Registra snippet provider *)
Disposable := TVSCodeCommands.RegisterCommand(
'wvds.ui.mycontrol.insert',
@InsertSnippet
);
AContext.Subscriptions.Push(Disposable);
end;
class procedure TExtension.Deactivate;
begin
(* Cleanup *)
end;
procedure InsertSnippet;
begin
asm
const snippet = '';
vscode.window.activeTextEditor?.insertSnippet(
new vscode.SnippetString(snippet)
);
end;
end;
exports
Activate,
Deactivate;
begin
end.
===== Passo 4: build.cfg =====
-Mobjfpc
-Tnodejs
-O-
-Jc
-Jirtl.js
-Fu../../../common
-FUpas
-FEdist
-odist/extension_main.js
===== Passo 5: Compilare =====
$ExtPath = "sources/extensions/wvds.vscode.ui.controls/editors/wvds.vscode.ui.mycontrol"
# Compilare con pas2js
pas2js @"$ExtPath/build.cfg" "$ExtPath/pas/extension_main.pas"
===== Passo 6: Pacchettizzare VSIX =====
cd $ExtPath
# Copiare icona (se non presente)
if (-not (Test-Path "images")) {
New-Item -ItemType Directory -Path "images" -Force
Copy-Item "%MEDIA%/wvds_fpc.png" "images/icon.png"
}
# Creare VSIX
vsce package --no-dependencies
# Spostare in dist
Move-Item "*.vsix" "%BINARIES%/dist/"
===== Definizione Snippet =====
Crea ''snippets/mycontrol.json'':
{
"WvdS MyControl": {
"prefix": "wvds-mycontrol",
"body": [
""
],
"description": "Insert WvdS MyControl"
}
}
===== Esempio Completo =====
==== Extension Button ====
library extension_main;
{$mode objfpc}
{$modeswitch externalclass}
uses
JS, Web,
VSCode.Base, VSCode.Commands, VSCode.Window,
VSCode.Languages, VSCode.CompletionItem;
const
CONTROL_NAME = 'Button';
CONTROL_CATEGORY = 'Basic Controls';
CONTROL_ICON = 'symbol-event';
type
TButtonExtension = class
public
class procedure Activate(AContext: TVSCodeExtensionContext);
class procedure Deactivate;
private
class procedure RegisterSnippet(AContext: TVSCodeExtensionContext);
class procedure RegisterCompletionProvider(AContext: TVSCodeExtensionContext);
end;
class procedure TButtonExtension.Activate(AContext: TVSCodeExtensionContext);
begin
RegisterSnippet(AContext);
RegisterCompletionProvider(AContext);
asm
console.log('WvdS UI: Button extension activated');
end;
end;
class procedure TButtonExtension.Deactivate;
begin
(* Cleanup *)
end;
class procedure TButtonExtension.RegisterSnippet(AContext: TVSCodeExtensionContext);
var
Cmd: TVSCodeDisposable;
begin
Cmd := TVSCodeCommands.RegisterCommand(
'wvds.ui.button.insert',
procedure
begin
asm
const editor = vscode.window.activeTextEditor;
if (editor) {
const snippet = new vscode.SnippetString(
''
);
editor.insertSnippet(snippet);
}
end;
end
);
AContext.Subscriptions.Push(Cmd);
end;
class procedure TButtonExtension.RegisterCompletionProvider(
AContext: TVSCodeExtensionContext);
begin
(* Provider completamento PXAML *)
asm
const provider = vscode.languages.registerCompletionItemProvider(
{ language: 'pxaml', scheme: 'file' },
{
provideCompletionItems(document, position) {
const item = new vscode.CompletionItem('Button', vscode.CompletionItemKind.Class);
item.insertText = new vscode.SnippetString(
''
);
item.documentation = 'WvdS Button control';
return [item];
}
},
'<'
);
AContext.subscriptions.push(provider);
end;
end;
procedure Activate(AContext: TJSObject);
begin
TButtonExtension.Activate(TVSCodeExtensionContext(AContext));
end;
procedure Deactivate;
begin
TButtonExtension.Deactivate;
end;
exports
Activate,
Deactivate;
begin
end.
===== Generazione Batch =====
Per piu control, vedi [[.:control-generierung|Generazione Control]].
===== Troubleshooting =====
==== Errori pas2js ====
| Errore | Soluzione |
^ ''class var'' non supportato | Usare variabile a livello Unit |
^ ''Int64'' non supportato | Usare ''Integer'' |
^ ''//'' in blocco asm | ''/* */'' per commenti JS |
==== Errori VSIX ====
| Errore | Soluzione |
^ Missing publisher | Impostare ''publisher'' in package.json |
^ Icon not found | Creare ''images/icon.png'' |
^ Invalid main | Verificare percorso in ''main'' |
===== Vedi anche =====
* [[.:control-generierung|Generazione Control]]
* [[.:control-architektur|Architettura Control]]
* [[.:extension-entwicklung|Sviluppo Extension]]