vscode插件开发总结

article/2025/10/4 5:30:23

一、关于vscode插件

相信大家对vscode应该都不陌生,VSCode是微软出的一款轻量级代码编辑器,免费而且功能强大,以功能强大、提示友好、不错的性能和颜值俘获了大量开发者的青睐,对JavaScript和NodeJS的支持非常好,自带很多功能,例如代码格式化,代码智能提示补全、颜色高亮插件等。

再强大的IDE那也不可能面面俱到什么功能都塞进去,那样只会导致IDE本身太臃肿。功能嘛,按需索取,所以,vscode的很多强大功能都是基于插件实现的,IDE只提供一个最基本的框子和最基本功能,由插件来丰富和扩展它的功能。

vscode插件可以很轻松的在应用商店搜索并下载到,应用商店官网是:https://marketplace.visualstudio.com/vscode ,vscode推出时间本身并不长,但生态发展得非常好,应用商店已经有各种各样丰富的插件供大家使用了。

二、HelloWorld

官方脚手架
安装脚手架:

npm install -g yo generator-code

然后cd到你的工作目录,运行yo code

在这里插入图片描述
项目结构其实很简单,主要是清单文件package.json以及extension.js这个插件入口文件:
在这里插入图片描述
package.json部分关键内容如下(已省略其它)

{// 扩展的激活事件"activationEvents": ["onCommand:extension.sayHello"],// 入口文件"main": "./src/extension",// 贡献点,vscode插件大部分功能配置都在这里"contributes": {"commands": [{"command": "extension.sayHello","title": "Hello World"}]}
}

src/extension.js内容如下:

const vscode = require('vscode');/*** 插件被激活时触发,所有代码总入口* @param {*} context 插件上下文*/
exports.activate = function(context) {console.log('恭喜,您的扩展“vscode-plugin-demo”已被激活!');// 注册命令context.subscriptions.push(vscode.commands.registerCommand('extension.sayHello', function () {vscode.window.showInformationMessage('Hello World!');}));
};/*** 插件被释放时触发*/
exports.deactivate = function() {console.log('您的扩展“vscode-plugin-demo”已被释放!')
};

解读

  • main定义了整个插件的主入口;
  • 我们在contributes.commands里面注册了一个名为extension.sayHello的命令,并在src/extension.js中去实现了它(弹出一个Hello World的提示);
  • 但是仅仅这样还不够,命令虽然定义了,但是vscode还不知道啥时候去执行它,还需要在activationEvents添加上onCommand:extension.sayHello用来告诉vscode,当用户执行了这个命令操作时去执行前面我们定义的内容;
  • 除了onCommand之外,还有onViewonUrionLanguage等等

运行调试

按下F5就会弹出一个新的vscode窗口:

这个新窗口已经加载了我们的插件,窗口标题会注明扩展开发主机,对于只有单显示器的同学来说,很容易写着写着就忘了哪个是主窗口,哪个是新窗口,所以可以通过这个来区分。

在这里插入图片描述
为了描述方便,我们约定,后续把新弹出来的那个窗口叫新窗口,之前老的那个叫旧窗口

然后按下Ctrl+Shift+P,输入HelloWorld执行对应命令,当你发现右下角弹出了HelloWorld的提示时,恭喜你,你已经掌握了插件开发基本技巧。

三、package.json

package.json

{// 插件的名字,应全部小写,不能有空格"name": "vscode-plugin-demo",// 插件的友好显示名称,用于显示在应用市场,支持中文"displayName": "VSCode插件demo",// 描述"description": "VSCode插件demo集锦",// 关键字,用于应用市场搜索"keywords": ["vscode", "plugin", "demo"],// 版本号"version": "1.0.0",// 发布者,如果要发布到应用市场的话,这个名字必须与发布者一致"publisher": "sxei",// 表示插件最低支持的vscode版本"engines": {"vscode": "^1.27.0"},// 插件应用市场分类,可选值: [Programming Languages, Snippets, Linters, Themes, Debuggers, Formatters, Keymaps, SCM Providers, Other, Extension Packs, Language Packs]"categories": ["Other"],// 插件图标,至少128x128像素"icon": "images/icon.png",// 扩展的激活事件数组,可以被哪些事件激活扩展,后文有详细介绍"activationEvents": ["onCommand:extension.sayHello"],// 插件的主入口"main": "./src/extension",// 贡献点,整个插件最重要最多的配置项"contributes": {// 插件配置项"configuration": {"type": "object",// 配置项标题,会显示在vscode的设置页"title": "vscode-plugin-demo","properties": {// 这里我随便写了2个设置,配置你的昵称"vscodePluginDemo.yourName": {"type": "string","default": "guest","description": "你的名字"},// 是否在启动时显示提示"vscodePluginDemo.showTip": {"type": "boolean","default": true,"description": "是否在每次启动时显示欢迎提示!"}}},// 命令"commands": [{"command": "extension.sayHello","title": "Hello World"}],// 快捷键绑定"keybindings": [{"command": "extension.sayHello","key": "ctrl+f10","mac": "cmd+f10","when": "editorTextFocus"}],// 菜单"menus": {// 编辑器右键菜单"editor/context": [{// 表示只有编辑器具有焦点时才会在菜单中出现"when": "editorFocus","command": "extension.sayHello",// navigation是一个永远置顶的分组,后面的@6是人工进行组内排序"group": "navigation@6"},{"when": "editorFocus","command": "extension.demo.getCurrentFilePath","group": "navigation@5"},{// 只有编辑器具有焦点,并且打开的是JS文件才会出现"when": "editorFocus && resourceLangId == javascript","command": "extension.demo.testMenuShow","group": "z_commands"},{"command": "extension.demo.openWebview","group": "navigation"}],// 编辑器右上角图标,不配置图片就显示文字"editor/title": [{"when": "editorFocus && resourceLangId == javascript","command": "extension.demo.testMenuShow","group": "navigation"}],// 编辑器标题右键菜单"editor/title/context": [{"when": "resourceLangId == javascript","command": "extension.demo.testMenuShow","group": "navigation"}],// 资源管理器右键菜单"explorer/context": [{"command": "extension.demo.getCurrentFilePath","group": "navigation"},{"command": "extension.demo.openWebview","group": "navigation"}]},// 代码片段"snippets": [{"language": "javascript","path": "./snippets/javascript.json"},{"language": "html","path": "./snippets/html.json"}],// 自定义新的activitybar图标,也就是左侧侧边栏大的图标"viewsContainers": {"activitybar": [{"id": "beautifulGirl","title": "美女","icon": "images/beautifulGirl.svg"}]},// 自定义侧边栏内view的实现"views": {// 和 viewsContainers 的id对应"beautifulGirl": [{"id": "beautifulGirl1","name": "国内美女"},{"id": "beautifulGirl2","name": "国外美女"},{"id": "beautifulGirl3","name": "人妖"}]},// 图标主题"iconThemes": [{"id": "testIconTheme","label": "测试图标主题","path": "./theme/icon-theme.json"}]},// 同 npm scripts"scripts": {"postinstall": "node ./node_modules/vscode/bin/install","test": "node ./node_modules/vscode/bin/test"},// 开发依赖"devDependencies": {"typescript": "^2.6.1","vscode": "^1.1.6","eslint": "^4.11.0","@types/node": "^7.0.43","@types/mocha": "^2.2.42"},// 后面这几个应该不用介绍了"license": "SEE LICENSE IN LICENSE.txt","bugs": {"url": "https://github.com/sxei/vscode-plugin-demo/issues"},"repository": {"type": "git","url": "https://github.com/sxei/vscode-plugin-demo"},// 主页"homepage": "https://github.com/sxei/vscode-plugin-demo/blob/master/README.md"
}

activationEvents

插件在VS Code中默认是没有被激活的,哪什么时候才被激活呢?就是通过activationEvents来配置,目前支持一下8种配置:

  • onLanguage:${language}
  • onCommand:${command}
  • onDebug
  • workspaceContains:${toplevelfilename} //每当打开一个文件夹并且该文件夹包含至少一个匹配的文件时,就会发出此激活事件并且感兴趣的扩展将被激活。
  • onFileSystem:${scheme} // 读取来自特定方案的文件或文件夹时,都会发出此激活事件
  • onView:${viewId} //只要在 VS Code 侧边栏中展开指定 id 的视图,就会发出此激活事件
  • onUri // 每当打开该扩展的系统范围 Uri 时,就会发出此激活事件
  • *

都比较好懂,我就不做一一介绍了,举个例子,如果我配置了`onLanguage:javascript``,那么只要我打开了JS类型的文件,插件就会被激活。

重点说一下*,如果配置了*,只要一启动vscode,插件就会被激活,为了出色的用户体验,官方不推荐这么做。看到这里相信大家知道了我们前面HelloWord里面为啥要配置onCommand了吧。

contributes

  • configuration:设置
  • commands:命令
  • menus:菜单
  • keybindings:快捷键绑定
  • languages:新语言支持
  • debuggers:调试
  • breakpoints:断点
  • grammars 语法
  • themes:主题
  • snippets:代码片段
  • jsonValidation:自定义JSON校验
  • views:左侧侧边栏视图
  • viewsContainers:自定义activitybar
  • problemMatchers 匹配器
  • problemPatterns // 文档中只写了同上
  • taskDefinitions 任务
  • colors 主题颜色

参考

https://code.visualstudio.com/api/references/extension-manifest

https://code.visualstudio.com/api/references/activation-events

https://code.visualstudio.com/api/references/contribution-points

四、命令、菜单、快捷键

命令

我们在前面HelloWord章节中已经提到了命令写法,这里再重温一下。

context.subscriptions.push(vscode.commands.registerCommand('extension.sayHello', () => {vscode.window.showInformationMessage('您执行了extension.sayHello命令!');
}));

然后在清单文件声明:

"commands": [{"command": "extension.sayHello","title": "Hello World"},
]

vscode.commands.registerCommand是注册命令的API,执行后会返回一个Disposable对象,所有注册类的API执行后都需要将返回结果放到context.subscriptions中去。

回调函数参数

回调函数接收一个可选参数uri

  • 当从资源管理器中右键执行命令时会把当前选中资源路径uri作为参数传过;
  • 当从编辑器中右键菜单执行时则会将当前打开文件路径URI传过去;
  • 当直接按Ctrl+Shift+P执行命令时,这个参数为空;

示例:

context.subscriptions.push(vscode.commands.registerCommand('extension.demo.getCurrentFilePath', (uri) => {vscode.window.showInformationMessage(`当前文件(夹)路径是:${uri ? uri.path : '空'}`);
}));

package.json如下:

	"menus": {"editor/context": [{"when": "editorFocus","command": "extension.demo.getCurrentFilePath","group": "navigation"}],"explorer/context": [{"command": "extension.demo.getCurrentFilePath","group": "navigation"}]}}

最终效果:

在这里插入图片描述

编辑器命令

除了上面的注册普通命令之外,还有一个vscode.commands.registerTextEditorCommand命令,文本编辑器命令与普通命令不同,它们仅在有被编辑器被激活时调用才生效,此外,这个命令可以访问到当前活动编辑器textEditor

// 编辑器命令
context.subscriptions.push(vscode.commands.registerTextEditorCommand('extension.testEditorCommand', (textEditor, edit) => {console.log('您正在执行编辑器命令!');console.log(textEditor, edit);
}));

执行命令

这里先说一下vscode api的一个习惯设计,很多命令都是返回一个类似于Promise的Thenable对象,如果发现api里面返回的是这个对象,说明这个方法不是直接返回结果的。

使用代码执行某个命令:

vscode.commands.executeCommand('命令', 'params1', 'params2', ...).then(result => {console.log('命令结果', result);
});

获取所有命令

前面说到了执行命令,那我怎么知道某些操作它的命令是什么呢?

有2种方法,第一种通过代码,getCommands接收一个参数表示是否过滤内部命令,默认否:

// 获取所有命令
vscode.commands.getCommands().then(allCommands => {console.log('所有命令:', allCommands);
});

一般有上千个命令:
在这里插入图片描述
另外一种方法是直接打开快捷键设置,这里就能看到所有命令列表,右键可以复制命令:

在这里插入图片描述

复杂命令

vscode内部有一些复杂命令,所谓复杂命令,就是指一些需要特殊参数并且通常有返回值、执行一些诸如跳转到定义、执行代码高亮等特殊操作、这类命令有几十个,作为插件开发者,很多时候你可能正需要这类命令,复杂命令列表参阅:
https://code.visualstudio.com/docs/extensionAPI/vscode-api-commands

以下是演示如何在VS代码中打开新文件夹的示例:

let uri = Uri.file('/some/path/to/folder');
commands.executeCommand('vscode.openFolder', uri).then(sucess => {console.log(success);
});

菜单

一个菜单项的完整配置如下:

"contributes": {"menus": {"editor/title": [{"when": "resourceLangId == markdown","command": "markdown.showPreview","alt": "markdown.showPreviewToSide","group": "navigation"}]}
}
  • editor/title是key值,定义这个菜单出现在哪里;
  • when控制菜单合适出现;
  • command定义菜单被点击后要执行什么操作;
  • alt定义备用命令,按住alt键打开菜单时将执行对应命令;
  • group定义菜单分组;

出现的位置

目前插件可以给以下场景配置自定义菜单:

  • 资源管理器上下文菜单 - explorer/context
  • 编辑器上下文菜单 - editor/context
  • 编辑标题菜单栏 - editor/title
  • 编辑器标题上下文菜单 - editor/title/context
  • 调试callstack视图上下文菜单 - debug/callstack/context
  • SCM标题菜单 -scm/title
  • SCM资源组菜单 -scm/resourceGroup/context
  • SCM资源菜单 -scm/resource/context
  • SCM更改标题菜单 -scm/change/title
  • 左侧视图标题菜单 -view/title
  • 视图项菜单 -view/item/context
  • 控制命令是否显示在命令选项板中 - commandPalette

其中,最常见的应该就explorer/contexteditor/context了,这2个应该不用多做介绍。

editor/title
在这里插入图片描述
图标在commands里面配置,light和dark分别对应浅色和深色主题,如果不配置图标则直接显示文字:

"commands": [{"command": "extension.demo.testMenuShow","title": "这个菜单仅在JS文件中出现","icon": {"light": "./images/tool-light.svg","dark": "./images/tool-light.svg"}}
]

editor/title/context:
在这里插入图片描述

when

通过可选的when语句,VS Code可以很好地控制什么时候显示菜单项,当然,when语句语法不仅仅适用于菜单项的控制。

when语句语法有很多,这里列举几个常用的:

  • resourceLangId == javascript:当编辑的文件是js文件时;
  • resourceFilename == test.js:当当前打开文件名是test.js时;
  • isLinux、isMac、isWindows:判断当前操作系统;
  • editorFocus:编辑器具有焦点时;
  • editorHasSelection:编辑器中有文本被选中时;
  • view == someViewId:当当前视图ID等于someViewId时;
  • 等等等

多个条件可以通过与或非进行组合,例如:editorFocus && isWindows && resourceLangId == javascript

有关when语句的更多完整语法请参考官方文档:

https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts

alt

alt很好理解,表示没有按下alt键时,点击右键菜单执行的是command对应的命令,而按下了alt键后执行的是alt对应的命令。

右键group

组间排序

控制菜单的分组和排序。不同的菜单拥有不同的默认分组。

editor/context中有这些默认组:

  • navigation- 放在这个组的永远排在最前面;
  • 1_modification - 更改组;
  • 9_cutcopypaste - 编辑组
  • z_commands - 最后一个默认组,其中包含用于打开命令选项板的条目。
    在这里插入图片描述
    除了navigation是强制放在最前面之外,其它分组都是按照0-9、a-z的顺序排列的,所以如果你想在1_modification9_cutcopypaste插入一个新的组别的话,你可以定义一个诸如6_test

在这里插入图片描述
explorer/context有这些默认组:

  • navigation - 放在这个组的永远排在最前面;
  • 2_workspace - 与工作空间操作相关的命令。
  • 3_compare - 与差异编辑器中的文件比较相关的命令。
  • 4_search - 与在搜索视图中搜索相关的命令。
  • 5_cutcopypaste - 与剪切,复制和粘贴文件相关的命令。
  • 7_modification - 与修改文件相关的命令。

编辑器选项卡上下文菜单有这些默认组:

  • 1_close - 与关闭编辑器相关的命令。
  • 3_preview - 与固定编辑器相关的命令。

editor/title有这些默认组:

  • 1_diff - 与使用差异编辑器相关的命令。
  • 3_open - 与打开编辑器相关的命令。
  • 5_close - 与关闭编辑器相关的命令。

组内排序

默认同一个组的顺序取决于菜单名称,如果想自定义排序的话可以再组后面通过@<number>的方式来自定义顺序,例如:

"editor/context": [{"when": "editorFocus","command": "extension.sayHello",// 强制放在navigation组的第2个"group": "navigation@2"},{"when": "editorFocus","command": "extension.demo.getCurrentFilePath",// 强制放在navigation组的第1个"group": "navigation@1"}
]

如上,默认情况下,按照菜单名排序,sayHellogetCurrentFilePath的前面,但是通过自定义顺序,把后者放到了前面。

快捷键

快捷键设置的写法比较简单,如下所示:

"contributes": {"keybindings": [{// 指定快捷键执行的操作"command": "extension.sayHello",// windows下快捷键"key": "ctrl+f10",// mac下快捷键"mac": "cmd+f10",// 快捷键何时生效"when": "editorTextFocus"}]
}

这个快捷键最终会出现在整个vscode快捷键设置界面:
在这里插入图片描述
如果您想了解更多有关快捷键绑定的详细细节可以继续阅读官方文档:
https://code.visualstudio.com/docs/getstarted/keybindings

五、WebView

大家都知道,整个VSCode编辑器就是一张大的网页,其实,我们还可以在Visual Studio Code中创建完全自定义的、可以间接和nodejs通信的特殊网页(通过一个acquireVsCodeApi特殊方法),这个网页就叫WebView。内置的Markdown的预览就是使用WebView实现的。使用Webview可以构建复杂的、支持本地文件操作的用户界面。

VSCode插件的WebView类似于iframe的实现,但并不是真正的iframe(我猜底层应该还是基于iframe实现的,只不过上层包装了一层),通过开发者工具可以看到.

在这里插入图片描述

什么时候适合使用WebView

虽然Webview令人很振奋,因为基于它我们可以随意发挥不受限制,但必须注意还是要慎用,毕竟VSCode是很注重性能的,不能因为你一个插件拖累了整个IDE,一般仅在原有API和功能以及交互方式无法满足你时才需要考虑,另外,设计糟糕的Webview也很容易在VS Code中让人感觉不舒适,不能让人家一看就觉得你这是一张网页,好看的UI也很重要。

这是官网给出的建议,在使用webview之前请考虑以下事项:

  • 这个功能真的需要放在VSCode中吗?作为单独的应用程序或网站会不会更好呢?
  • webview是实现这个功能的唯一方法吗?可以使用常规VS Code API吗?
  • 您的webview是否会带来足够的用户价值以证明其高资源成本?

创建WebView

context.subscriptions.push(vscode.commands.registerCommand('extension.demo.openWebview', function (uri) {// 创建webviewconst panel = vscode.window.createWebviewPanel('testWebview', // viewType"WebView演示", // 视图标题vscode.ViewColumn.One, // 显示在编辑器的哪个部位{enableScripts: true, // 启用JS,默认禁用retainContextWhenHidden: true, // webview被隐藏时保持状态,避免被重置});panel.webview.html = `<html><body>你好,我是Webview</body></html>`

几点说明:

  • 默认情况下,在Web视图中禁用JavaScript,但可以通过传入enableScripts: true选项轻松启用;
  • 默认情况下当webview被隐藏时资源会被销毁,通过retainContextWhenHidden: true会一直保存,但会占用较大内存开销,仅在需要时开启;

加载本地资源

出于安全考虑,Webview默认无法直接访问本地资源,它在一个孤立的上下文中运行,想要加载本地图片、js、css等必须通过特殊的vscode-resource:协议,网页里面所有的静态资源都要转换成这种格式,否则无法被正常加载。

vscode-resource:协议类似于file:协议,但它只允许访问特定的本地文件。和file:一样,vscode-resource:从磁盘加载绝对路径的资源。

我简单封装了一个转换方法:

import * as vscode from 'vscode';export class Util {public static buildPath(data: string, webview: vscode.Webview, contextPath: string): string {return data.replace(/((src|href)=("|')?)(\/\/)/gi, "$1http://").replace(/((src|href)=("|'))((?!(http))[^"']+?\.(css|js|properties|json|png|jpg))\b/gi, "$1" + webview.asWebviewUri(vscode.Uri.file(`${contextPath}`)) + "/$4");}
}

转换之后 -》例:https://file+.vscode-resource.vscode-webview.net/Users/liuchongyang/site/vscode/extensions/a-text-verify/media/image/u187.png

从文件加载HTML内容

import { readFileSync } from 'fs';
import { Util } from './common/util';
...
workbenchPanel.webview.html = Util.buildPath(readFileSync(`${this._extensionUri.path}/media/workbench.html`, 'utf8').replace("{{rootPath}}", rootPath).replace("{{baseUrl}}", workbenchPanel.webview.asWebviewUri(this._extensionUri).toString()),workbenchPanel.webview, contextPath);

消息通信

重头戏来了,Webview和普通网页非常类似,不能直接调用任何VSCodeAPI,但是,它唯一特别之处就在于多了一个名叫acquireVsCodeApi的方法,执行这个方法会返回一个超级阉割版的vscode对象,这个对象里面有且仅有如下3个可以和插件通信的API:
在这里插入图片描述
插件和Webview之间如何互相通信呢?
插件给Webview发送消息(支持发送任意可以被JSON化的数据)

panel.webview.postMessage({text: '你好,我是小茗同学!'});

Webview端接收:

window.addEventListener('message', event => {const message = event.data;console.log('Webview接收到的消息:', message);
}

Webview主动发送消息给插件:

vscode.postMessage({text: '你好,我是Webview啊!'});

插件接收:

panel.webview.onDidReceiveMessage(message => {console.log('插件收到的消息:', message);
}, undefined, context.subscriptions);

state

在webview的js中我们可以使用vscode.getState()vscode.setState()方法来保存和恢复JSON可序列化状态对象。当webview被隐藏时,即使webview内容本身被破坏,这些状态仍然会保存。当然了,当webview被销毁时,状态将被销毁。

序列化

通过注册WebviewPanelSerializer可以实现在VScode重启后自动恢复你的webview,当然,序列化其实也是建立在getStatesetState之上的。

注册方法:vscode.window.registerWebviewPanelSerializer

retainContextWhenHidden

对于具有非常复杂的UI或状态且无法快速保存和恢复的webview,我们可以直接使用retainContextWhenHidden选项。设置retainContextWhenHidden: true后即使webview被隐藏到后台其状态也不会丢失。

尽管retainContextWhenHidden很有吸引力,但它需要很高的内存开销,一般建议在实在没办法的时候才启用。
getStatesetState是持久化的首选方式,因为它们的性能开销要比retainContextWhenHidden低得多。

六、实现案例

关键字高亮实现

extension.ts

import * as vscode from 'vscode'
import { decorate } from './decorator';export function activate(context: vscode.ExtensionContext) {vscode.workspace.onDidSaveTextDocument(e => {decorate()})vscode.workspace.onDidChangeTextDocument(e => {decorate()})vscode.workspace.onDidOpenTextDocument(e => {decorate()})vscode.window.onDidChangeVisibleTextEditors(e => {decorate();})
}export function deactivate() { }

decorator.ts

import * as vscode from "vscode"
import { rainborColors } from "./rainbow";
import { clearLine } from "readline";let colors = Array.from(rainborColors)
let rainbows = colors.map(x => vscode.window.createTextEditorDecorationType({ color: x }))function getRandomInt(min: number, max: number): number {return Math.floor(Math.random() * (max - min + 1)) + min;
}function replaceComments(buffer: string) {var comment = /\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gmreturn buffer.replace(comment, (x) => {var len = x.lengthvar r = " ".repeat(len)return r})
}function notContains<T>(datas: Array<T>, value: T) {return datas.indexOf(value) == -1;
}export function decorate() {let editor = vscode.window.activeTextEditor;let allText = editor.document.getText()let noCommentText = replaceComments(allText)// let regex = /(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)')|`([^`\\]*(?:\\.[^`\\]*)*)`)/g;// let regex = /(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)')/g;// let regex = /\"(.*)\"/g;let regex = /(北京)|(沧海)|(夕)|(兮)|(十年生死)|(茫茫)|(不思量)|(自难忘)/g;let decorators = colors.map(color => [])let match: RegExpMatchArray;let offset: number = getRandomInt(0, colors.length);// console.log(888, regex.exec(noCommentText))while ((match = regex.exec(noCommentText))) {// console.log('match[1]', match); //['"好啊后"', '好啊后', index: 8, input: '好玩 111  "好啊后"', groups: undefined]let chars: string[] = [...(match[0] || match[1] || match[2])];offset--;let startWord = match.index + 1let endWord = startWord + chars.lengthchars.forEach((_, i) => {var matchIndex = match.index + 1let rainbowIndex = Math.abs((i + offset) % colors.length);let startIndex = matchIndex + i - 1let endIndex = matchIndex + ilet start = editor.document.positionAt(startIndex)let end = editor.document.positionAt(endIndex)decorators[rainbowIndex].push(new vscode.Range(start, end))});}decorators.forEach((d, index) => {editor.setDecorations(rainbows[index], d)})
}

rainbow.ts

function byte2Hex(n) {var nybHexString = "0123456789ABCDEF"return String(nybHexString.substr((n >> 4) & 0x0F, 1)) + nybHexString.substr(n & 0x0F, 1)
}function RGB2Color(r, g, b) {return '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b)
}function* makeColorGradient(frequency1, frequency2, frequency3, phase1, phase2, phase3, center = 128, width = 127, len = 50) {for (var i = 0; i < len; ++i) {var red = Math.sin(frequency1 * i + phase1) * width + centervar grn = Math.sin(frequency2 * i + phase2) * width + centervar blu = Math.sin(frequency3 * i + phase3) * width + centeryield RGB2Color(red, grn, blu)}
}// export const rainborColors = makeColorGradient(.3, .3, .3, 0, 2, 4)
export const rainborColors = makeColorGradient(.2, .2, .2, 0, 2, 4)

在这里插入图片描述

文章片段

在这里插入图片描述
package.json

{"name": "plaintext","displayName": "%displayName%","description": "%description%","version": "1.0.0","publisher": "vscode","license": "MIT","engines": {"vscode": "0.10.x"},"contributes": {"configurationDefaults": {"[plaintext]": {"editor.maxTokenizationLineLength": 2500}},"languages": [{"id": "plaintext","aliases": ["plaintext","txt"],"extensions": [".txt"]}],"snippets": [{"language": "plaintext","path": "./snippets/plaintext.code-snippets"}]},"repository": {"type": "git","url": "https://github.com/microsoft/vscode.git"}
}

plaintext.code-snippets

{"大连文章": {"prefix": "沧海","body": ["曾经沧海难为水","除却巫山不是云","曾经沧海难为水","除却巫山不是云","曾经沧海难为水","除却巫山不是云","曾经沧海难为水","除却巫山不是云","曾经沧海难为水","除却巫山不是云","曾经沧海难为水","除却巫山不是云"],"description": "好诗啊好诗"},"大连文章c": {"prefix": "沧海","body": ["秋风清,秋月明,","落叶聚还散,寒鸦栖复惊。","相思相见知何日?此时此夜难为情!","入我相思门,知我相思苦,","长相思兮长相忆,短相思兮无穷极,","早知如此绊人心,何如当初莫相识。",],"description": "好诗啊好诗"},"大连文章a": {"prefix": "断肠","body": ["十年生死两茫茫,不思量,自难忘。千里孤坟,无处话凄凉。纵使相逢应不识,尘满面,鬓如霜。","夜来幽梦忽还乡,小轩窗,正梳妆。相顾无言,惟有泪千行。料得年年肠断处,明月夜,短松冈。",],"description": "好诗啊好诗"},"大连文章b": {"prefix": "断肠","body": ["今夕何夕兮,搴舟中流。","蒙羞被好兮,不訾诟耻","今日何日兮,得与王子同舟。","心几烦而不绝兮,得知王子。"],"description": "好诗啊好诗"}
}

添加背景色

在这里插入图片描述

let decorationType = vscode.window.createTextEditorDecorationType({backgroundColor: 'red',});
let editor = vscode.window.activeTextEditor;
editor.setDecorations(decorationType, [new vscode.Range(0, 3, 0, 4), new vscode.Range(0, 1, 0, 2)]);

文本替换

// 通过科大讯飞返回值转化vscode位置规范
const range = new vscode.Range(editor.document.positionAt(Number(message.value.pos)),editor.document.positionAt(Number(message.value.pos)+ message.value.word.length));if (editor) {const document = editor.document;const selection = editor.selection;// var p1 = new vscode.Position(0,79);// var p2 = new vscode.Position(0,99);// var r = new vscode.Range(p1,p2);// const word = document.getText(r)editor.edit(editBuilder => {editBuilder.replace(range  , message.value.word);});

大纲视图

在这里插入图片描述

/*---------------------------------------------------------------------------------------------*  Copyright (c) Microsoft Corporation. All rights reserved.*  Licensed under the MIT License. See License.txt in the project root for license information.*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
const laws = ['合同法', '劳动法', '民法典', '宪法', '刑法', '教育法', '治安管理处罚条例', '婚姻法', '隐私保护法', '民事诉讼法', '人民法院在线诉讼规则', '中华人民共和国人民法院法庭规则', '最高人民法院关于互联网法院审理案件若干问题的规定', '法庭纪律'];
const providerDocumentSymbol = (context: vscode.ExtensionContext) => {context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider({language: "lawdawn"}, new FooDocumentSymbolProvider()));
};
class FooDocumentSymbolProvider implements vscode.DocumentSymbolProvider {public provideDocumentSymbols(document: vscode.TextDocument,token: vscode.CancellationToken): Thenable<vscode.DocumentSymbol[]> {return new Promise((resolve, reject) => {let symbols: vscode.DocumentSymbol[] = [];for(let i = 0; i < document.lineCount; i++) {let line = document.lineAt(i);for (let j = 0; j < laws.length; j++) {if (line.text.includes(laws[j])) {symbols.push(new vscode.DocumentSymbol(laws[j], line.text, vscode.SymbolKind.Key, line.range,  line.range ));}}}resolve(symbols);});}
}export default providerDocumentSymbol;
/*---------------------------------------------------------------------------------------------*  Copyright (c) Microsoft Corporation. All rights reserved.*  Licensed under the MIT License. See License.txt in the project root for license information.*--------------------------------------------------------------------------------------------*/
import providerDocumentSymbol from './language-extensions/outline';export function activate(context: vscode.ExtensionContext) {// 大纲providerproviderDocumentSymbol(context);
}

比较好的文章可供参考:

https://zhaomenghuan.js.org/note/vscode/awesome-vscode.html

https://zhuanlan.zhihu.com/p/99587182

插件:https://www.kancloud.cn/shangyewangchuan/vs_code/972974
坑:如果启动不来,去掉环境变量unset ELECTRON_RUN_AS_NODE

vscode插件demo: https://github.com/microsoft/vscode-extension-samples

在这里插入图片描述


http://chatgpt.dhexx.cn/article/tIjdl6b5.shtml

相关文章

2021-前端-VsCode插件

此乃吾习前端&#xff0c;VsCode之插件&#xff0c;个人所装&#xff0c;喜着自拿&#xff0c;不足之处还望海涵&#xff0c;多加批评。 1.Auto Close Tag——自动闭合尾部的标签 2.Atuo Rename Tag——修改 html 标签 自动帮你完成头部和尾部闭合标签的同步修改 3.Bracket…

关于VSCode插件的安装位置

VSCode的插件地址修改_上善若泪-CSDN博客_vscode插件位置文章目录1 data文件夹2 使用--extensions-dir命令3 使用mklink命令vscode编辑器强大的地方是可以使用各种各样的插件&#xff0c;但是插件默认的地方是在:C盘&#xff0c;让一些强迫症可能会受不了&#xff0c;非要迁移到…

vscode 插件-常用插件

VSCode常用插件(安装步骤同汉化) 1、*Auto Close Tag (自动闭合HTML/XML标签) 2、*Auto Rename Tag (自动帮你完成尾部闭合标签的同步修改&#xff0c;不过有些bug) 3、*Prettier(Prettier 是目前 Web 开发中最受欢迎的代码格式化程序) 安装Prettier -Code formatter这个插件…

Vscode 插件包下载并离线安装

打开VSCode插件官网 官网链接是https://marketplace.visualstudio.com/vscode 搜索Go 在输入框中输入go&#xff0c;搜索&#xff0c;结果如下&#xff1a; 点击Download Extension下载 注意&#xff1a;有时候找不到Download Extension&#xff0c;可能是网速加载慢&…

VsCode插件安装及推荐

1、快捷键Ctrl P&#xff0c;打开插件&#xff0c;输入 ext install &#xff08;我习惯的输入方式&#xff09;&#xff1b; 2、或者点击图片中的圈红的按钮&#xff0c;也可以进入插件安装商城&#xff1b; 3、下面开始说下我目前安装的插件&#xff08;我目前是vue开发&…

VScode安装离线插件

1. 下载及安装 首先在VScode官方插件库下载自己所需要的插件&#xff1a;https://marketplace.visualstudio.com/vscode 下载成功之后是以**.vsix**结尾的文件 然后再VScode软件中进行导入刚下载的文件 如果提示蓝色信息则为安装成功&#xff0c;红色则为失败 2. 版本不兼容报…

VSCode前端必备插件

跨平台的文本编辑器。由于其卓越的性能和丰富的功能&#xff0c;它很快就受到了大家的喜爱。 就像大多数 IDE 一样&#xff0c;VSCode 也有一个扩展和主题市场&#xff0c;包含了数以千计质量不同的插件。为了帮助大家挑选出值得下载的插件&#xff0c;我们针对性的收集了一些…

如何写一个vscode插件

1.运行yo code创建项目 2.选择使用yarn或者npm 3.运行 官网这个例子需要我们 ctrl shirt p 调出输入框, 然后在里面输入hello w 就可以如图所示 activationEvents: 当什么情况下, 去激活这个插件 activationEvents.onCommand: 在某个命令下激活(之后会专门列出很多其他条件…

Python好用的VSCode插件

1. Better Comments 这是一个让你能更好地编写注释的工具&#xff0c;它能根据关键词用不同的颜色高亮代码片段。支持以下类型的高亮&#xff1a; 感叹号 “!” 代码警告。问号“?”代表存留疑问。TODO 代码未来将要进行的操作。param 参数 2. autoDocstring 能够自动生成函…

VScode插件(自用)

一、Material Icon Theme 图标插件 它采用了 Google Material Design 风格&#xff0c;文件图标以及文件夹图标覆盖非常的全面。 二、 颜色主题插件Themes&#xff08;代码颜色&#xff09;中的 Monokai Dimmed 三、css peek 使用此插件&#xff0c;你可以追踪至样式表中 CSS…

2022年好用的Vscode插件

Chinese(VSCode汉化插件) 第一款推荐的插件叫Chinese 是一款VSCode汉化插件 这样&#xff0c;VSCode就完成了汉化 Material Theme(主题插件) 第二款插件是一个好看的主题插件Material Theme 它包含了多套不同色彩风格的主题&#xff0c;以及好看的图标样式。 选择不同主题可以…

VSCode 插件

文章目录 VSCode 插件 VSCode 插件 图标插件作用Auto Import在j\ts文件中&#xff0c;直接使用外部依赖包的变量名&#xff0c;此时&#xff0c;会自动写入导入语句Bracket Pair Colorizer2VS Code 已经内置Chinese (Simplified) (简体中文)汉化Code Spell Checker适用于代码和…

vscode常用插件总结

1、Code Spell Checker 检查单词拼写 2、Auto Rename Tag html/xml标签改变&#xff0c;将会成对改变&#xff5e; 3、Color Highlight 颜色标记 4、vscode-icon 文件图标 5、Turbo Console Log 或者 javascript console utils 按ctrlAltL可以快速输出console.log 6、v…

vscode插件(个人正在用的)

插件目录 any-ruleAuto Close TagAuto Rename Tagbackground-coverChinese (Simplified) (简体中文) Language Pack for Visual Studio CodeDebugger for JavaError LensESLintExtension Pack for JavaImage previewIntelliCodeIntelliCode API Usage ExamplesLanguage Support…

Vue3 (Vscode插件)

前端开发的编辑器有很多种如DW,hubilder&#xff0c;Web Storm,sublime,vscode&#xff0c;等等。 Vue3 vite Ts pinia 实战 源码 全栈_哔哩哔哩_bilibili 视频教程 随着VsCode开源免费&#xff0c;丰富的插件&#xff0c;也是深受前端开发人员爱戴&#xff0c;在我们使…

vscode插件开发

目录 插件在 VSCode 中能做什么 1、发布应用市场 1、申请Microsoft账号 2、创建Azure DevOps组织 3、创建令牌 4、创建发布账号 5、发布应用市场 2、本地打包不发布 1、本地打包 2、导入应用商店 ​编辑 3、插件开发前的环境准备 2、项目初始化 3、运行项目 4、文件…

VSCode插件推荐

1. VSCode汉化包插件 &#xff1a;Chinese (Simplified) (简体中文) Language VSCode汉化包&#xff0c;原始默认是英文的所以我们需要下一个中文插件。 2. VSCode自动补全标签 &#xff1a;Auto Close Tag Auto Close Tag 对Html或Xml文件自动创建结束标签&#xff1b; 如在…

vscode常用插件大全

vscode常用插件大全 参考文章 https://mp.weixin.qq.com/s/1PkWPApvn5uWJl_cdzcoTA 说明 该片文章基本介绍了 vscode 常用插件 , 已经很全面 本文不做任何编辑器的比较&#xff0c;只是我本人日常使用 vscode 进行开发&#xff0c;并且比较喜欢折腾 vscode &#xff0c;会到处…

最新最全 VSCODE 插件推荐(2023版)

目录 一、主题及图标 二、功能强化 三、Git 集成 四、数据库 五、编程美化 六、开发效率 七、前端开发 八、数据分析 九、修仙插件 一、主题及图标 GitHub Theme 黑白两款皮肤 Material Theme 集成了多种主题皮肤&#xff0c;搭配 Material Icon Theme 食用更佳…

千锋重庆web前端技术分享之前端VSCode常用插件

一、VSCode常用的插件vscode之所以被称为宇宙第一神器&#xff0c;其中丰富的插件功不可没&#xff0c;安装起来超级简单&#xff0c;给我们开发带来了极大的便捷。 注意&#xff0c;新手学习期间&#xff0c;不建议安装形形色色的插件&#xff0c;用到啥就安装啥。因为有些插件…