前言
最近在进行一些 api 文档的开发。想着能否开发一个 vscode weapp api
类似 api 智能提示 vscode 插件。让开发者可以得到自己开发 api 的补全提示。话不多说,让我们仅用三分钟学会如何开发一个 api 补全提示的 vscode 插件。
快速开发
使用现成的 vscode 官方插件示例进行开发
git 地址:https:github.com/microsoft/vscode-extension-samples
clone 下来后打开 completions-sample 文件夹进行开发。
npm i
以后使用 vscode 的 debug 界面 Run Extension 就可以调试插件了
示例的代码比较简单,我们把它改造成可以根据一个对象自动生成 providers 。
coding
代码比较简单,直接贴上来了。
import * as vscode from "vscode";
interface CompletionItem extends vscode.CompletionItem {
// 对应语言
selector?: vscode.DocumentSelector;
prefix?: string;
items?: CompletionItem[];
}
// 把这个数据结构转换为 Provider 数组
const completionArr: CompletionItem[] = [
{
selector: ["typescript", "javascript", "plaintext"],
label: "selfApi",
items: [
{
label: "api",
items: [
{
label: "Context",
kind: vscode.CompletionItemKind.Variable,
items: [
{
label: "getActiveUser",
kind: vscode.CompletionItemKind.Function,
items: [
{
label: "getUserInfo",
kind: vscode.CompletionItemKind.Function,
},
],
},
{
label: "getUserAgent",
kind: vscode.CompletionItemKind.Function,
},
{
label: "getLocaleLang",
kind: vscode.CompletionItemKind.Function,
},
],
},
],
},
],
},
];
const providerList: vscode.Disposable[] = [];
const getProviders = (
CompletionItemArr: CompletionItem[] | CompletionItem[]
): vscode.Disposable[] => {
CompletionItemArr.forEach((CompletionItem) => {
const completion = providerFactory(CompletionItem);
providerList.push(completion);
if (CompletionItem.items) {
CompletionItem.items.forEach((item) => {
const middle =
(CompletionItem?.kind === vscode.CompletionItemKind.Function
? "()"
: "") + ".";
item.prefix = CompletionItem.label + middle + item.label;
item.selector = CompletionItem.selector;
});
getProviders(CompletionItem.items);
}
});
return providerList;
};
const providerFactory = (
completionItem: CompletionItem | CompletionItem
): vscode.Disposable => {
const { selector = [], label, items, prefix = "", kind } = completionItem;
return vscode.languages.registerCompletionItemProvider(
selector,
{
provideCompletionItems(
document: vscode.TextDocument,
position: vscode.Position
) {
const linePrefix = document
.lineAt(position)
.text.substr(0, position.character);
// function 的匹配规则可以使用正则来匹配包含参数的情况
const endsStr = `${label}${
kind === vscode.CompletionItemKind.Function ? "()" : ""
}.`;
if (!items || !linePrefix.endsWith(endsStr)) {
return undefined;
}
const completionItems = items.map(
({ label, kind, documentation = "" }) => {
const completion = new vscode.CompletionItem(label, kind);
completion.documentation = documentation;
return completion;
}
);
return completionItems;
},
},
"."
);
};
export function activate(context: vscode.ExtensionContext) {
const providers = getProviders(completionArr);
context.subscriptions.push(...providers);
}
当我们输入selfApi.api
时会提示有Context
属性;输入selfApi.api.Context.getActiveUser()
时会提示有getUserInfo
方法。
发布 vscode 插件
发布插件,juejin.cn/post/711909… 写的很详细