vscode代码补全插件用多了,感觉不如自己写一个

120 阅读5分钟

说在前面

🤯上一篇文章中我们制作了一个代码片段管理插件,但是用起来感觉有那么一点不顺手,如果将插入代码片段的功能改为代码自动补全提示来直接选择插入呢?这样用起来是不是就不一样了,今天我们就在代码片段管理插件的基础上实现一个通过代码片段库来自动补全提示的功能📑

一、上期回顾

代码片段管理插件制作过程有兴趣的可以看下这篇文章:

《还在cv复用代码片段?试试自己写一个vscode插件来管理代码片段》

二、功能实现

1、代码补全提示

(1)获取代码片段

读取已保存的代码片段并进行解析。

const snippets = await getExtensionFile(context, "config/snippets.json");
completionItemsData = [];
for (const key in snippets) {
  completionItemsData.push({
    label: key,
    detail: "saveCodeSnippetsAndReusePlugins",
    documentation: snippets[key],
    insertText: snippets[key],
  });
}

各配置项说明如下:

  • label

提示面板显示的信息,如下图的gcd

  • detail

提示面板右侧显示的补充说明信息,如下图的saveCodeSnippetsAndReusePlugins

  • documentation

提示面板右侧显示的详细文档说明,如下图

  • insertText

选择该项时插入到代码中的文本内容,及需要插入的代码片段内容,选择后回车及会插入,如下图,我们选择了gcd后则将我们保存的gcd函数插入代码中了。

(2)provideCompletionItems方法

  • 该方法接收document(当前编辑的文件对象)、position(光标位置)、token(用于取消操作的令牌,通常在异步操作中使用)和context(提供了关于当前代码提示上下文的一些信息)等参数。
  • 它的主要作用是根据completionItemsData数组中的数据生成并返回一系列CompletionItem对象,这些对象将作为代码补全提示展示给用户。具体来说,它遍历completionItemsData数组,为每个元素创建一个CompletionItem对象,并设置其label(显示给用户的文本标签)、detail(补充说明信息)、documentation(详细文档说明)和insertText(用户选择该项时插入到代码中的文本内容)等属性。
function provideCompletionItems(document, position, token, context) {
  return completionItemsData.map((item) => {
    const completionItem = new vscode.CompletionItem(item.label);
    completionItem.detail = item.detail;
    completionItem.documentation = item.documentation;
    completionItem.insertText = item.insertText;
    return completionItem;
  });
}

(3)resolveCompletionItem方法

  • 此方法接收completionItem(要解析的代码补全项对象)和token(用于取消操作的令牌)等参数。
  • 这里我们暂时不需要进行处理,直接返回即可。
function resolveCompletionItem(completionItem, token) {
  return completionItem;
}

(4)补全命令注册

  • 读取配置文件获取有效文件类型

读取config/config.json配置文件的内容,并获取其中的effectiveDocuments属性值,该值定义了哪些文件类型下代码补全提示应该生效。默认为:html,css,javascript,typescript,json,svg,less,sass,scss,vue,jsx,tsx,bat,sh

  • vscode.languages.registerCompletionItemProvider

    • 第一个参数,即语言标识符,指定了在哪些文件类型下触发代码补全提示。

    • 第二个参数是一个包含provideCompletionItems和resolveCompletionItem两个方法的对象,用于提供和解析代码补全项。

    • 第三个参数是一个空字符串,表示触发提示的字符列表为空,可能会根据默认规则触发补全。

  • 最后将注册的代码补全提供者对象completionProvider添加到context.subscriptions数组中,以便在插件失活等情况下自动清理相关资源。

const config = await getExtensionFile(context, "config/config.json");
const effectiveDocuments =
config.effectiveDocuments ||
"html,css,javascript,typescript,json,svg,less,sass,scss,vue,jsx,tsx,bat,sh";
// 注册代码提示提供者
completionProvider = vscode.languages.registerCompletionItemProvider(
effectiveDocuments.split(","), // 语言标识符,要与activationEvents中的设置匹配
{
  provideCompletionItems: provideCompletionItems,
  resolveCompletionItem: resolveCompletionItem,
},
""
);

context.subscriptions.push(completionProvider);

2、修改配置后刷新补全提示

  • 注销当前代码补全提供者(如果存在)

通过let tmp = await completionProvider;获取当前的代码补全提供者对象(如果已经注册),然后判断如果tmp不为空,则调用tmp.dispose();方法注销当前的代码补全提供者,释放相关资源。

  • 重新调用codeSnippetsTip函数:

在注销当前代码补全提供者后,调用codeSnippetsTip(context);重新执行代码片段补全提示的初始化操作,包括重新读取配置文件、更新completionItemsData数组以及重新注册代码补全提供者等,从而实现刷新代码片段补全提示的功能。

async function refreshCodeSnippetsTip(context) {
  let tmp = await completionProvider;
  if (tmp) tmp.dispose();
  codeSnippetsTip(context);
}

三、插件使用

1、插件安装

直接在vscode插件商场中搜索saveCodeSnippetsAndReusePlugins

点击安装即可:

2、仓库配置

需要配置以下三个信息:

  • token

在gitee设置中生成然后复制填写即可:

  • owner

  • repo

前面准备工作中新建的仓库,填写仓库名

3、代码片段同步

在多机使用时,可以同步拉取其他电脑保存的代码片段

4、保存代码片段

  • 快捷键(ctrl + alt + s)

将选中的代码保存为代码片段,可以自己命名

5、插入代码片段

  • 快捷键(ctrl + alt + i)

选择已保存的代码片段插入到当前代码

6、删除代码片段

  • 快捷键(ctrl + alt + d)

选择需要删除的代码片段进行删除

7、代码片段自动补全

根据已保存的代码片段生成自动补全提示,快速将已保存的代码片段插入当前代码中。

8、代码片段补全语言类型

  • 快捷键(ctrl + alt + e)

配置代码补全语言标识符,即需要触发代码片段补全的语言类型,默认为:html,css,javascript,typescript,json,svg,less,sass,scss,vue,jsx,tsx,bat,sh,在配置好的这些语言类型文件编辑中才会触发代码片段补全功能

源码

组件库已开源,有兴趣的也可以到这里看看:

gitee

gitee.com/zheng_yongt…

github

github.com/yongtaozhen…

🌟觉得有帮助的可以点个star~

🖊有什么问题或错误可以指出,欢迎pr~

📬有什么想要实现的功能或想法可以联系我~

公众号

关注公众号『前端也能这么有趣』,获取更多有趣内容。

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。