vsCode-custom-editor

521 阅读2分钟

如何在编辑器中开发一个画图功能

VS Code API

vscode module

catScratchEdit

实现表情生成功能,点击button会随机生成一个猫咪的表情,通过这个例子

  1. 了解webview和插件通信
  2. 如何注册编辑器事件和registerCustomEditorProvider提供者
  3. vsCode.Range的使用
// catScratch.js
const addButtonContainer = document.querySelector('.add-button');
	addButtonContainer.querySelector('button').addEventListener('click', () => {
		vscode.postMessage({
			type: 'add'
		});
	})

// 插件接收webview消息
webviewPanel.webview.onDidReceiveMessage(e => {
			switch (e.type) {
				case 'add':
					this.addNewScratch(document);
					return;

				case 'delete':
					this.deleteScratch(document, e.id);
					return;
			}
		});

点击button给webview发送添加的消息,webview接收消息后,执行插件addNewScratch方法,将要添加表情。

public static register(context: vscode.ExtensionContext): vscode.Disposable {
		const provider = new CatScratchEditorProvider(context);
		const providerRegistration = vscode.window.registerCustomEditorProvider(CatScratchEditorProvider.viewType, provider);
		return providerRegistration;
	}

// package.json
"activationEvents": [
		"onCustomEditor:catCustoms.catScratch",
	],

注册编辑器事件,传入provider提供者,并且package.json加入贡献点,激活事件。

private updateTextDocument(document: vscode.TextDocument, json: any) {
		const edit = new vscode.WorkspaceEdit();

		// Just replace the entire document every time for this example extension.
		// A more complete extension should compute minimal edits instead.
		edit.replace(
			document.uri,
			new vscode.Range(0, 0, document.lineCount, 0),
			JSON.stringify(json, null, 2));

		return vscode.workspace.applyEdit(edit);
	}
//  通知webview
function updateWebview() {
			webviewPanel.webview.postMessage({
				type: 'update',
				text: document.getText(),
			});
		}

随机一个表情,根据document.uriRang替换成新的表情,更新后通知webview更新了。

pawDrawEditor

实现在编辑器中可以对图片涂鸦,通过这个例子可以了解

  1. 如何实现二进制文件的自定义编辑器
  2. webview应用
  3. 使用CustomDocuments存储多个自定义编辑器之间共享的信息
  4. 实现保存、撤消、重做和还原
  5. 备份自定义编辑器

初始化canvas后,通知插件准备好,执行openCustomDocument

第一次打开给定CustomEditorProvider编辑器时,会调用openCustomDocument,然后将文档传递给resolveCustomEditor,以便向用户显示编辑器,。

插件给webview发送getFileData,画布插入初始化图片完成后回传ready

webview收到ready 发送init

vscode.postMessage({ type: 'ready' }); // 初始化canvs后,通知插件准备好,执行openCustomDocument

async openCustomDocument(
		uri: vscode.Uri,
		openContext: { backupId?: string },
		_token: vscode.CancellationToken
	): Promise<PawDrawDocument> {
		const document: PawDrawDocument = await PawDrawDocument.create(uri, openContext.backupId, {
			getFileData: async () => {
				const webviewsForDocument = Array.from(this.webviews.get(document.uri));
				if (!webviewsForDocument.length) {
					throw new Error('Could not find webview to save for');
				}
				const panel = webviewsForDocument[0];
				const response = await this.postMessageWithResponse<number[]>(panel, 'getFileData', {});
				return new Uint8Array(response);
			}
		});

webview执行初始化事件绑定,setable是所有按钮实现点击

_initElements(/** @type {HTMLElement} */ parent) {
			const colorButtons = /** @type {NodeListOf<HTMLButtonElement>} */ (document.querySelectorAll('.drawing-controls button'));
			for (const colorButton of colorButtons) {
				colorButton.addEventListener('click', e => {
					e.stopPropagation();
					colorButtons.forEach(button => button.classList.remove('active'));
					colorButton.classList.add('active');
					this.drawingColor = colorButton.dataset['color'];
				});
			}

设置retainContextWhenHidden后,将webview一直处于激活状态,存储的数据会被保存下来。

默认情况下,VS Code 只允许每个自定义文档有一个编辑器,如果想要多个需要开启supportsMultipleEditorsPerDocument

return vscode.window.registerCustomEditorProvider(
			PawDrawEditorProvider.viewType,
			new PawDrawEditorProvider(context),
			{
				// For this demo extension, we enable `retainContextWhenHidden` which keeps the
				// webview alive even when it is not visible. You should avoid using this setting
				// unless is absolutely required as it does have memory overhead.
				webviewOptions: {
					retainContextWhenHidden: true,
				},
				supportsMultipleEditorsPerDocument: false,
			});