diff --git a/CHANGELOG.md b/CHANGELOG.md index ce5b6b7..2c7923a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.0.3 (2024/06/25) + +- Update readme. + +## 0.0.2 (2024/06/25) + +- Add pickers for proto. + ## 0.0.1 (2024/06/25) - Initial release. diff --git a/README.md b/README.md index e64076f..4e73cb9 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,4 @@ # protoviewer -Display proto file contents in VSCode. - - -Add the following to your settings: -```json -"protoviewer": { - "proto-path": "/path/to/your/protobuf_file.proto", - "message-name": "MessageName" -} -``` +Display proto file contents in VSCode. Just open any file with a `pb` in the +extension, choose a proto file, and a message from that file. \ No newline at end of file diff --git a/package.json b/package.json index 1914b6a..f9074f5 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "protoviewer", "displayName": "protoviewer", "description": "Display protofbuf files in VSCode.", - "version": "0.0.1", + "version": "0.0.3", "engines": { "vscode": "^1.75.0" }, @@ -18,6 +18,7 @@ "categories": [ "Visualization" ], + "publisher": "mosum", "keywords": [ "protobuf" ], @@ -34,7 +35,7 @@ "displayName": "Protobuf Preview", "selector": [ { - "filenamePattern": "*pb" + "filenamePattern": "*.*pb" } ] } diff --git a/src/extension.ts b/src/extension.ts index ea60101..79f57f5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,7 +4,8 @@ import { ProtoCustomProvider } from './protoProvider'; export function activate(context: ExtensionContext): void { const extensionRoot = Uri.file(context.extensionPath); // Register our custom editor provider - const provider = new ProtoCustomProvider(extensionRoot); + const provider = new ProtoCustomProvider(extensionRoot, context); + context.subscriptions.push( window.registerCustomEditorProvider( ProtoCustomProvider.viewType, diff --git a/src/protoPreview.ts b/src/protoPreview.ts index 8f5ebe6..7fe1ee8 100644 --- a/src/protoPreview.ts +++ b/src/protoPreview.ts @@ -1,6 +1,7 @@ import * as vscode from 'vscode'; import { Disposable } from './disposable'; import { decodeProtobuf } from './protoparser'; +import protobuf = require('protobufjs'); type PreviewState = 'Disposed' | 'Visible' | 'Active'; @@ -10,7 +11,8 @@ export class ProtoPreview extends Disposable { constructor( private readonly extensionRoot: vscode.Uri, private readonly resource: vscode.Uri, - private readonly webviewEditor: vscode.WebviewPanel + private readonly webviewEditor: vscode.WebviewPanel, + private readonly context: vscode.ExtensionContext ) { super(); const resourceRoot = resource.with({ @@ -67,14 +69,18 @@ export class ProtoPreview extends Disposable { } }) ); - - this.webviewEditor.webview.html = this.getWebviewContents(); - this.update(); + this.getWebviewContents(context).then((html) => { + this.webviewEditor.webview.html = html; + this.update(); + }); } private reload(): void { if (this._previewState !== 'Disposed') { - this.webviewEditor.webview.postMessage({ type: 'reload' }); + this.getWebviewContents(this.context).then((html) => { + this.webviewEditor.webview.html = html; + this.update(); + }); } } @@ -90,30 +96,78 @@ export class ProtoPreview extends Disposable { this._previewState = 'Visible'; } - private getWebviewContents(): string { + private async getWebviewContents( + context: vscode.ExtensionContext + ): Promise { const webview = this.webviewEditor.webview; const docPath = webview.asWebviewUri(this.resource); - - const config = vscode.workspace.getConfiguration('protoviewer'); - const protoPath = vscode.Uri.parse(config.get('proto-path')); - const messageName = config.get('message-name') as string; - console.log(config); - + const protos = JSON.parse( + context.globalState.get('protoviewer.protos') ?? '[]' + ) as string[]; + const quickPick = await vscode.window.showQuickPick( + [...protos, 'Add new proto'], + { + canPickMany: false, + } + ); const head = ` `; - const body = - messageName == null || protoPath == null - ? 'Please add your proto-path and message-name args' - : `
` +
-          decodeProtobuf(docPath, protoPath, messageName) +
-          `
`; - const tail = [''].join('\n'); - - return head + body + tail; + let body: string; + if (quickPick) { + let result: vscode.Uri | undefined; + if (quickPick == 'Add new proto') { + const filePick = await vscode.window.showOpenDialog({ + openLabel: 'Add proto', + canSelectMany: false, + filters: { + Protobuffer: ['proto'], + }, + }); + if (filePick) { + result = filePick[0]; + + protos.push(result.path); + context.globalState.update( + 'protoviewer.protos', + JSON.stringify(protos) + ); + } + } else { + result = vscode.Uri.parse(quickPick); + } + if (result) { + const root = protobuf.loadSync(result.path); + console.log(root); + const messageNames = root.nestedArray + .map((value) => { + return (value as protobuf.Namespace).nestedArray; + }) + .reduce((accumulator, value) => accumulator.concat(value), []) + .map((value) => { + return value.name; + }); + const messageNamePick = await vscode.window.showQuickPick( + messageNames, + { + canPickMany: false, + } + ); + if (messageNamePick) { + body = + messageNamePick == null + ? 'Please add your proto-path and message-name args' + : `
` +
+                decodeProtobuf(docPath, root, messageNamePick) +
+                `
`; + return head + body + tail; + } + } + } + return head + 'No proto selected' + tail; } } diff --git a/src/protoProvider.ts b/src/protoProvider.ts index fc649b4..821cbbf 100644 --- a/src/protoProvider.ts +++ b/src/protoProvider.ts @@ -8,7 +8,10 @@ export class ProtoCustomProvider private readonly _previews = new Set(); private _activePreview: ProtoPreview | undefined; - constructor(private readonly extensionRoot: vscode.Uri) {} + constructor( + private readonly extensionRoot: vscode.Uri, + private readonly context: vscode.ExtensionContext + ) {} public openCustomDocument(uri: vscode.Uri): vscode.CustomDocument { return { uri, dispose: (): void => {} }; @@ -21,7 +24,8 @@ export class ProtoCustomProvider const preview = new ProtoPreview( this.extensionRoot, document.uri, - webviewEditor + webviewEditor, + this.context ); this._previews.add(preview); this.setActivePreview(preview); diff --git a/src/protoparser.ts b/src/protoparser.ts index f98d916..b71fe67 100644 --- a/src/protoparser.ts +++ b/src/protoparser.ts @@ -4,15 +4,14 @@ import fs = require('fs'); export function decodeProtobuf( filePath: Uri, - protoPath: Uri, + root: protobuf.Root, messageType: string ): string { const buffer = fs.readFileSync(filePath.path); try { - const root = protobuf.loadSync(protoPath.path); const decoded = root.lookupType(messageType).decode(buffer); return JSON.stringify(decoded.toJSON(), null, ' '); } catch (error) { - return `Error decoding ${filePath} with ${protoPath} and ${messageType}`; + return `Error decoding ${filePath} with ${root} and ${messageType}`; } }