Guide to creating a VSIX Extension for a WvdS Control.
Each WvdS Control is distributed as a standalone VSIX Extension:
wvds-vscode-ui-{control}-0.1.0.vsix
├── package.json # Extension Manifest
├── dist/
│ └── extension_main.js # Compiled Code
├── images/
│ └── icon.png # Extension Icon
└── pas/
└── extension_main.pas # Pascal source code
sources/extensions/wvds.vscode.ui.controls/
├── {category}/
│ └── wvds.vscode.ui.{control}/
│ ├── package.json
│ ├── build.cfg
│ ├── pas/
│ │ └── extension_main.pas
│ └── dist/ # Build output
│ └── extension_main.js
$ControlName = "mycontrol" $Category = "editors" $BasePath = "sources/extensions/wvds.vscode.ui.controls" New-Item -ItemType Directory -Path "$BasePath/$Category/wvds.vscode.ui.$ControlName/pas" -Force
{ "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" }
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 (* Register 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.
-Mobjfpc -Tnodejs -O- -Jc -Jirtl.js -Fu../../../common -FUpas -FEdist -odist/extension_main.js
$ExtPath = "sources/extensions/wvds.vscode.ui.controls/editors/wvds.vscode.ui.mycontrol" # Compile with pas2js pas2js @"$ExtPath/build.cfg" "$ExtPath/pas/extension_main.pas"
cd $ExtPath # Copy icon (if not present) if (-not (Test-Path "images")) { New-Item -ItemType Directory -Path "images" -Force Copy-Item "%MEDIA%/wvds_fpc.png" "images/icon.png" } # Create VSIX vsce package --no-dependencies # Move to dist Move-Item "*.vsix" "%BINARIES%/dist/"
Create snippets/mycontrol.json:
{ "WvdS MyControl": { "prefix": "wvds-mycontrol", "body": [ "<MyControl", " Name=\"${1:myControl1}\"", " ${2:Property}=\"${3:Value}\"", "/>" ], "description": "Insert WvdS MyControl" } }
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 (* PXAML completion provider *) 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.
For multiple controls, see Control Generation.
| Error | Solution |
class var not supported | Use Unit-Level Variable |
|---|---|
Int64 not supported | Use Integer |