前言
我们的目标是实现一个基础库的插件,其功能包含以下内容:
- 语法校验,校验API命令调用的正确性,参数类型的正确性,参数个数的正确性,关键参数和系统打通校验有效性等
- 语法自动补全,辅助用户编写代码
- 语法悬停提示,辅助说明语法
- 其他功能
- webview查看远程信息
本篇即为悬停语法提示&webview实现篇,我们先看一下最后的效果,是不是很神奇,快来和我一起探讨到底是怎么实现的吧~
悬停提示:
查看更多信息:
完整代码可在我的github中查看。
一、语法悬停提示
1.1 语法说明
registerHoverProvider(selector: DocumentSelector, provider: HoverProvider): Disposable
1.2 实现
如tyc_test下有一个testA方法
// client/src/config/doc.ts
const doc = [
{
kind: 'Function',
body: [
"testA"
],
detail: "(method) tyc_test.testA( key: string, value: any)",
documentation: `测试testA自动补全
@param key — 要设置的字段名.
@param value — 要设置的值.`
}
];
import * as vscode from 'vscode';
import { file } from '../config';
class HoverProvider {
provideHover(document: vscode.TextDocument, position: vscode.Position) {
const text = document.getText(new vscode.Range(
new vscode.Position(0, 0),
position
));
const word = document.getText(document.getWordRangeAtPosition(position));
if(/tyc_test\.[A-Za-z]+$/g.test(text)) {
for(let i = 0; i < doc.length; i++ ) {
const regExp = RegExp(`${doc[i].body[0]}`);
// 检查当前语法是否有文档,检测关键字
if(regExp.test(word)){
const description = doc[i].documentation.replace(/\@/g,function(m,n){
return `\n${m}`;
});
return new vscode.Hover([doc[i].detail,description]);
}
}
};
}
}
export default function(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.languages.registerHoverProvider(file, new HoverProvider()));
};
在插件入口文件引入:
// client/src/extension.ts
import hoverInfo from './provider/hoverInfo';
export function activate(context: vscode.ExtensionContext) {
// 悬浮提示
hoverInfo(context);
}
1.3 效果
二、查看更多信息(webview)
2.1 语法说明
createWebviewPanel(viewType: string, title: string, showOptions: ViewColumn | {preserveFocus: boolean, viewColumn: ViewColumn}, options?: WebviewPanelOptions & WebviewOptions): WebviewPanel
2.2 实现
我们的交互设计为当选中任意内容后,右键可以查看其详细信息,我们这里仅示意,展示你选中的内容,实际上你可以根据你的需求,发挥你的想象力,做更多的事情,比如异步获取一些系统的信息展示
首先我们需要注册一个命令,这里我们将命令绑定到了右键菜单上,同时设置了快捷键
"contributes": {
"commands": [
{
"command": "vscode-example-tyc.preview", // 注册一个命令
"title": "查看更多信息"
}
],
"keybindings": [
{
"command": "vscode-example-tyc.preview", // 新增一个快捷键
"key": "ctrl+l",
"mac": "cmd+l",
"when": "editorHasSelection"
}
],
"menus": {
"editor/context": [
{
"when": "editorHasSelection", // 声明一个菜单项
"command": "vscode-example-tyc.preview",
"group": "navigation"
}
]
}
}
创建webview主体逻辑
// client/src/provider/createWebview.ts
import * as vscode from 'vscode';
import { render } from './render/index';
let panel = null;
const preview = vscode.commands.registerCommand('vscode-example-tyc.preview', async function (uri) {
let editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showWarningMessage('请新开一个文件使用');
return;
}
let selection = editor.selection;
const document=editor.document;
let text = document.getText(selection);
if (!text) {
return;
};
if (!panel || panel._store._isDisposed) {
panel = createWebviewPanel();
}
// 设置文档内容
panel.webview.html = render(text);
});
function createWebviewPanel() {
let panel = vscode.window.createWebviewPanel(
'vscode-example-tyc',
'查看更多信息',
vscode.ViewColumn.Two, {
enableScripts: true,
retainContextWhenHidden: false,
}
);
panel.onDidDispose(async (event) => {
});
return panel;
}
export default function(context: vscode.ExtensionContext) {
context.subscriptions.push(preview);
};
在插件入口文件引入
// client/src/extension.ts
import createWebview from './provider/createWebview';
export function activate(context: vscode.ExtensionContext) {
// 创建webview
createWebview(context);
}
2.3 效果
2.4 如何调试webview
按下Ctrl+Shift+P
然后执行打开Webview开发工具
(Open Webview Developer Tools
)
调试界面:
2.5 高级内容
Webview出于安全考虑,默认无法直接访问本地资源,如果需要想要加载本地图片、js、css等必须通过特殊的vscode-resource:
协议,网页里面所有的静态资源都要转换成这种格式,否则无法被正常加载
如果需要和vscode有交互,需要使用其消息通信API
,这里就不赘述了,感兴趣的可以阅读blog.haoji.me/vscode-plug…了解更多