VSCodium and Antigravity
This commit is contained in:
parent
a0e35dd7e1
commit
7bb2ddcaea
@ -39,20 +39,31 @@ is available on the SheetJS Git server. Feedback and contributions are welcome!
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was verified in the following deployments:
|
||||
This demo was tested in the following deployments:
|
||||
|
||||
| Platform | Architecture | Date |
|
||||
|:-------------------|:-------------|:-----------|
|
||||
| VSCodium 1.109 | `darwin-arm` | 2026-03-05 |
|
||||
| VS Code 1.110.0 | `win11-arm` | 2026-03-05 |
|
||||
| Antigravity 1.19.6 | `linux-arm` | 2026-03-05 |
|
||||
| Platform | Architecture | Date |
|
||||
|:--------------------------------------------------|:-------------|:-----------|
|
||||
| [VSCodium 1.109.51242](https://vscodium.com/) | `darwin-arm` | 2026-03-05 |
|
||||
| [VS Code 1.110.0](https://code.visualstudio.com/) | `win11-arm` | 2026-03-05 |
|
||||
| [Antigravity 1.19.6](https://antigravity.google/) | `linux-arm` | 2026-03-05 |
|
||||
|
||||
:::
|
||||
|
||||
:::danger Telemetry and Data Exfiltration
|
||||
|
||||
VSCode and many forks embed telemetry and send code to third-party servers.
|
||||
|
||||
For example, Antigravity includes AI features that are powered by Google Gemini
|
||||
and other cloud AI services. These features necessitate code exfiltration.
|
||||
|
||||
**[VSCodium](https://vscodium.com/) does not include AI features or telemetry!**
|
||||
|
||||
:::
|
||||
|
||||
## Integration Details
|
||||
|
||||
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
|
||||
imported from any component or script in the extension.
|
||||
imported from any script in the extension.
|
||||
|
||||
:::caution pass
|
||||
|
||||
@ -89,100 +100,156 @@ yarn add -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
|
||||
:::
|
||||
|
||||
## Extension Architecture
|
||||
The core extension APIs are available in the `vscode` package. A TypeScript
|
||||
extension typically uses "glob imports" to load SheetJS and VSCode features:
|
||||
|
||||
The VS Code Spreadsheet viewer extension has three main components:
|
||||
|
||||
- **Extension Entry Point:** Registers the extension with VS Code
|
||||
- **Custom Editor Provider:** Handles Excel files and converts them to web content
|
||||
- **WebView Content:** Displays Excel data as HTML tables
|
||||
|
||||
The extension uses VS Code's `Custom Editor API`[^2] to register as a handler for Excel files. When a file is opened,
|
||||
SheetJS parses it and displays the data in a WebView component.
|
||||
|
||||
### Extension Entry Point
|
||||
|
||||
The main entry point registers the custom editor provider:
|
||||
|
||||
```ts title="src/extension.ts"
|
||||
```ts title="Importing SheetJS and VSCode features"
|
||||
import * as vscode from 'vscode';
|
||||
// highlight-start
|
||||
import { ExcelEditorProvider } from './excelEditorProvider';
|
||||
// highlight-end
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// SheetJS Spreadsheet Viewer extension activating...
|
||||
// highlight-start
|
||||
const provider = ExcelEditorProvider.register(context);
|
||||
context.subscriptions.push(provider);
|
||||
// highlight-end
|
||||
}
|
||||
export function deactivate() {}
|
||||
import * as XLSX from 'xlsx';
|
||||
```
|
||||
|
||||
The `custom editor`[^4] is configured to support specific file types, giving us complete control over how each file is
|
||||
presented to the user. Additionally, `custom document`[^5] enables us to maintain and persist the state of each individual
|
||||
file that's opened.
|
||||
## Extension Architecture
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/excelEditorProvider.ts">
|
||||
{`import * as vscode from 'vscode';
|
||||
// highlight-start
|
||||
import * as XLSX from 'xlsx';
|
||||
import { ExcelDocument } from './excelDocument';
|
||||
// highlight-end
|
||||
VSCode Extensions for processing custom file types use the Custom Editor API[^2]
|
||||
for lifecycle events. This involves a number of moving parts:
|
||||
|
||||
// A simple class to store document state (one per opened file)
|
||||
class ExcelDocument implements vscode.CustomDocument {
|
||||
constructor(public readonly uri: vscode.Uri) {}
|
||||
dispose() {}
|
||||
1) "Custom Document" for managing file metadata
|
||||
|
||||
2) "Custom Editor Provider" for processing file data and generating previews
|
||||
|
||||
3) Registration during extension lifecycle events.
|
||||
|
||||
4) Advertisement of filetype support in extension metadata.
|
||||
|
||||
When a spreadsheet is opened, the extension will use SheetJS methods to parse
|
||||
the raw file and display the data in a HTML table.
|
||||
|
||||
### Custom Documents
|
||||
|
||||
Extensions must provide a class that implements `vscode.CustomDocument`[^4].
|
||||
|
||||
```ts title="Simple CustomDocument"
|
||||
class ExcelDocument implements vscode.CustomDocument {
|
||||
constructor(public readonly uri: vscode.Uri) { }
|
||||
dispose() { }
|
||||
}
|
||||
```
|
||||
|
||||
### Editor Provider
|
||||
|
||||
Extensions that read data should implement `vscode.CustomReadonlyEditorProvider`
|
||||
with a generic parameter for the custom document type.
|
||||
|
||||
The `openCustomDocument` method takes a `vscode.Uri` and is expected to return a
|
||||
new document:
|
||||
|
||||
```ts title="src/extension.ts (snippet)"
|
||||
class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
async openCustomDocument(uri: vscode.Uri): Promise<ExcelDocument> {
|
||||
return new ExcelDocument(uri);
|
||||
}
|
||||
|
||||
export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
// ...
|
||||
public static register(context: vscode.ExtensionContext): vscode.Disposable {
|
||||
return vscode.window.registerCustomEditorProvider(
|
||||
'excelViewer.spreadsheet',
|
||||
new ExcelEditorProvider(),
|
||||
{ webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
|
||||
);
|
||||
}
|
||||
// ...
|
||||
}`}
|
||||
</CodeBlock>
|
||||
}
|
||||
```
|
||||
|
||||
### Reading Files
|
||||
|
||||
The extension reads Excel files using the VS Code filesystem API and passes
|
||||
the data to SheetJS for parsing:
|
||||
The `FileSystemProvider` API[^5], available at `vscode.workspace.fs`, exposes
|
||||
common filesystem operations including reading raw data from files and watching
|
||||
for changes.
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/excelEditorProvider.ts">
|
||||
{`export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
The `resolveCustomEditor`[^6] method of the `CustomEditorProvider` will be
|
||||
called when a file is opened. The first argument is a `CustomDocument` whose
|
||||
`uri` property points to the location of the file.
|
||||
|
||||
`vscode.workspace.fs.readFile`[^5] returns a promise that resolves to a
|
||||
`Uint8Array` containing the raw binary data. This `Uint8Array` can be passed to
|
||||
the SheetJS [`read`](/docs/api/parse-options) method:
|
||||
|
||||
```ts title="src/extension.ts (snippet)"
|
||||
export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
// ...
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
// read the raw bytes from the file
|
||||
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
|
||||
|
||||
// parse the file data
|
||||
const wb: XLSX.WorkBook = XLSX.read(data);
|
||||
|
||||
// At this point, `wb` is a SheetJS Workbook Object
|
||||
// ...
|
||||
private async loadWorkbook(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<XLSX.WorkBook> {
|
||||
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
const options: XLSX.ParsingOptions = {
|
||||
type: 'array',
|
||||
cellStyles: true,
|
||||
cellDates: true,
|
||||
};
|
||||
### Previewing Data
|
||||
|
||||
return XLSX.read(new Uint8Array(data), options); // returns a XLSX.WorkBook
|
||||
}
|
||||
The `resolveCustomEditor`[^6] method of the `CustomEditorProvider` will be
|
||||
called when a file is opened. The second argument is a `WebviewPanel`[^7].
|
||||
|
||||
// This is called when the first time an editor for a given resource is opened
|
||||
async openCustomDocument(uri: vscode.Uri): Promise<ExcelDocument> {
|
||||
return new ExcelDocument(uri);
|
||||
}
|
||||
The `webview.html` nested property of the `WebviewPanel` controls the displayed
|
||||
HTML. Extensions can use SheetJS [API methods](/docs/api/).
|
||||
|
||||
// This is called whenever the user opens a new editor
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
const wb: XLSX.WorkBook = await this.loadWorkbook(document, webviewPanel);
|
||||
const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
webviewPanel.webview.html = \`<!DOCTYPE html><html><body>\${htmlTable}</body></html>\`;
|
||||
}
|
||||
}`}
|
||||
</CodeBlock>
|
||||
The SheetJS [`sheet_to_html`](/docs/api/utilities/html#html-table-output) method
|
||||
generates a simple HTML table. The following snippet displays the data of the
|
||||
first worksheet:
|
||||
|
||||
```ts title="src/extension.ts (snippet)"
|
||||
export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
// ...
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
// ...
|
||||
// continuing from "Reading Files", `wb` is a SheetJS Workbook Object
|
||||
const first_sheet = wb.Sheets[wb.SheetNames[0]];
|
||||
webviewPanel.webview.html = XLSX.utils.sheet_to_html(first_sheet);
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Registration
|
||||
|
||||
The exported `activate` method registers the editor provider. The first argument
|
||||
to `registerCustomEditorProvider` is expected to be a unique name that will be
|
||||
referenced later.
|
||||
|
||||
```ts title="src/extension.ts (snippet)"
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const provider = vscode.window.registerCustomEditorProvider(
|
||||
'excelViewer.spreadsheet',
|
||||
new ExcelEditorProvider(),
|
||||
{ webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
|
||||
);
|
||||
context.subscriptions.push(provider);
|
||||
}
|
||||
```
|
||||
|
||||
### Filetype Support
|
||||
|
||||
Extensions must announce custom editor file type support in `package.json`.
|
||||
The `selector` property[^8] is expected to include "Glob Pattterns"[^9].
|
||||
|
||||
The demo uses the following `package.json` snippet to announce support for `xls`
|
||||
and `xlsx` spreadsheets:
|
||||
|
||||
```json title="package.json (snippet)"
|
||||
"contributes": {
|
||||
"customEditors": [
|
||||
{
|
||||
// ... other properties including displayName
|
||||
// highlight-start
|
||||
// The viewType must match the first argument of `registerCustomEditorProvider`
|
||||
"viewType": "excelViewer.spreadsheet",
|
||||
"selector": [
|
||||
{ "filenamePattern": "*.xlsx" },
|
||||
{ "filenamePattern": "*.xls" }
|
||||
]
|
||||
// highlight-end
|
||||
}
|
||||
],
|
||||
// ...
|
||||
},
|
||||
```
|
||||
|
||||
### Usage Flow
|
||||
|
||||
@ -247,10 +314,9 @@ pnpm run watch
|
||||
`}
|
||||
</CodeBlock>
|
||||
|
||||
4) Launch a new editor window using the desired VSCode fork and open the newly
|
||||
created `sheetjs-demo` folder.
|
||||
4) Launch a new window with the VSCode fork and open the `sheetjs-demo` folder.
|
||||
|
||||
4) Save the following codeblock to `src/extension.ts`:
|
||||
5) Save the following codeblock to `src/extension.ts`:
|
||||
|
||||
```ts title="src/extension.ts (replace contents)"
|
||||
import * as vscode from 'vscode';
|
||||
@ -271,15 +337,11 @@ class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDo
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
|
||||
|
||||
const options: XLSX.ParsingOptions = {
|
||||
type: 'array',
|
||||
cellStyles: true,
|
||||
cellDates: true,
|
||||
};
|
||||
const options: XLSX.ParsingOptions = { cellStyles: true, cellDates: true };
|
||||
const wb: XLSX.WorkBook = XLSX.read(data, options);
|
||||
|
||||
const wb: XLSX.WorkBook = XLSX.read(new Uint8Array(data), options);
|
||||
const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
webviewPanel.webview.html = `<!DOCTYPE html><html><body>${htmlTable}</body></html>`;
|
||||
const first_sheet = wb.Sheets[wb.SheetNames[0]];
|
||||
webviewPanel.webview.html = XLSX.utils.sheet_to_html(first_sheet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +356,7 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
export function deactivate() {}
|
||||
```
|
||||
|
||||
5) Add the highlighted lines to the `contributes` section of `package.json`:
|
||||
6) Add the highlighted lines to the `contributes` section of `package.json`:
|
||||
|
||||
```json title="package.json (add highlighted lines)"
|
||||
"contributes": {
|
||||
@ -319,12 +381,12 @@ export function deactivate() {}
|
||||
},
|
||||
```
|
||||
|
||||
6) In the editor, open the Command Palette (Help > "Show All Commands" from the
|
||||
7) In the editor, open the Command Palette (Help > "Show All Commands" from the
|
||||
menu), type `Debug: Start` and select `Debug: Start Debugging`.
|
||||
|
||||
This will compile and run the extension in a new Extension Development Host window.
|
||||
|
||||
7) Drag and drop the `pres.xlsx` test file into the new window. If drag and drop
|
||||
8) Drag and drop the `pres.xlsx` test file into the new window. If drag and drop
|
||||
is not available, click "Open..." in the Welcome screen and select the file.
|
||||
|
||||
A new `pres.xlsx` tab will show the contents of the file.
|
||||
@ -350,5 +412,9 @@ demo was last tested, it was safe to set a minimum version of `^1.100.0`:
|
||||
[^1]: See [`Webview API`](https://code.visualstudio.com/api/extension-guides/webview) in the VSCode documentation for more details.
|
||||
[^2]: See [`Custom Editor API`](https://code.visualstudio.com/api/extension-guides/custom-editors) in the VSCode documentation for more details.
|
||||
[^3]: See [`vsce`](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#vsce) in the VSCode documentation for more details.
|
||||
[^4]: See [`Custom Editor`](https://code.visualstudio.com/api/extension-guides/custom-editors#custom-editor) in the VSCode documentation for more details.
|
||||
[^5]: See [`CustomDocument`](https://code.visualstudio.com/api/extension-guides/custom-editors#customdocument) in the VSCode documentation for more details.
|
||||
[^4]: See [`CustomDocument`](https://code.visualstudio.com/api/references/vscode-api#CustomDocument) in the VSCode API documentation for more details.
|
||||
[^5]: See [`FileSystemProvider`](https://code.visualstudio.com/api/references/vscode-api#FileSystemProvider) in the VSCode API documentation for more details.
|
||||
[^6]: See [`CustomEditorProvider<T>`](https://code.visualstudio.com/api/references/vscode-api#CustomEditorProvider<T>) in the VSCode API documentation for more details.
|
||||
[^7]: See [`WebviewPanel`](https://code.visualstudio.com/api/references/vscode-api#WebviewPanel) in the VSCode API documentation for more details.
|
||||
[^8]: See [`contributes.customEditors`](https://code.visualstudio.com/api/references/contribution-points#contributes.customEditors) in the VSCode API documentation for more details.
|
||||
[^9]: See ["Glob Patterns Reference"](https://code.visualstudio.com/docs/editor/glob-patterns) in the VSCode documentation for more details.
|
||||
Loading…
Reference in New Issue
Block a user