vscode api 补全插件开发

577 阅读1分钟

前言

最近在进行一些 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… 写的很详细