The attribute plugin is not available, 2fa disabled

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 = '<MyControl Name="myControl1" />';
    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": [
      "<MyControl",
      "    Name=\"${1:myControl1}\"",
      "    ${2:Property}=\"${3:Value}\"",
      "/>"
    ],
    "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(
            '<Button\n' +
            '    Name="${1:button1}"\n' +
            '    Caption="${2:Click Me}"\n' +
            '    OnClick="${3:OnButtonClick}"\n' +
            '/>'
          );
          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(
            '<Button Name="${1:button1}" Caption="${2:Click Me}" />'
          );
          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 Generazione Control.

Troubleshooting

Errori pas2js

Errore Soluzione
class var non supportato Usare variabile a livello Unit
Int64 non supportato Usare Integer
Zuletzt geändert: il 29/01/2026 alle 22:32