VsCode插件开发-01 基础开发入门
1 前置准备
1.1 安装脚手架工具
npm install -g yo generator-code
1.2 创建项目
yo code
按提示选择:
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? sensitive-scanner
? What's the identifier of your extension? sensitive-scanner
? What's the description of your extension? 检测敏感信息
? Initialize a git repository? Yes
? Which bundler to use? unbundled
? Which package manager to use? npm
1.3 项目结构
生成后的关键文件:
sensitive-scanner/
├── src/
│ └── extension.ts # 插件入口(主要编写代码的地方)
├── package.json # 插件配置(声明命令、配置项等)
└── tsconfig.json # TypeScript 配置
1.4 运行和调试
-
1. 用 VS Code 打开项目 -
2. 按 F5启动调试 -
3. 会打开一个新的 VS Code 窗口(扩展开发宿主) -
4. 在新窗口中测试你的插件
2 最简单的扫描器
目标:检测文件中的手机号码,用波浪线标记出来。
2.1 理解核心概念
用户编辑文件 → 插件获取文件内容 → 正则匹配 → 创建诊断信息 → 显示在编辑器中
2.2 修改 extension.ts
删除默认生成的代码,替换为:
import * as vscode from'vscode';
exportfunctionactivate(context: vscode.ExtensionContext){
console.log("指纹清除扫描器已激活");
// 创建诊断集合,这边是vscode自带的API
const diagnosticCollection = vscode.languages.createDiagnosticCollection("test-scanner");
// 监听文档变化事件,vscode自带
vscode.workspace.onDidChangeTextDocument(event => {
scanDocument(event.document,diagnosticCollection);
});
// 监听文档打开事件,vscode自带
vscode.workspace.onDidOpenTextDocument(doc => {
scanDocument(doc,diagnosticCollection);
});
// 扫描当前已打开的所有文档文件,vscode自带
vscode.workspace.textDocuments.forEach(doc => {
scanDocument(doc,diagnosticCollection);
});
// 注册到插件上下文,确保插件停用时清理资源
context.subscriptions.push(diagnosticCollection);
}
/**
* 1. document: vscode.TextDocument
* - 表示要扫描的文档对象
* - 包含文档的文本内容、文件路径、语言类型等信息
* 2. collection: vscode.DiagnosticCollection
* - 诊断集合,用于存储和显示代码问题
* - 可以在 VS Code 的"问题"面板中显示警告、错误等信息(就像 ESLint 或 TypeScript 显示的那些红色/黄色波浪线)
* @param document
* @param collection
*/
functionscanDocument(document: vscode.TextDocument,collection: vscode.DiagnosticCollection){
// 获取文档的全部内容
const text = document.getText();
// 简单的手机号正则
const phoneRegex = /1[3-9]\d{9}/g;
// 用于临时存储在当前文档中发现的所有问题
constdiagnostics: vscode.Diagnostic[] = [];
let match;
// 遍历所有信息进行匹配
/**
match 拿到的数据是一个数组(如果匹配成功)或 null(如果没有匹配)。
假设文本是:"联系我:13812345678",正则匹配到手机号,match 会是:
match = [
'13812345678', // match[0]: 完整匹配的字符串
// match[1], match[2]... 如果有捕获组,会在这里
]
// match 还有额外属性:
match.index = 4 // 匹配开始的位置(字符偏移量)
match.input = "联系我:13812345678" // 原始文本
关键点:
- match[0] = 匹配到的完整字符串
- match.index = 匹配开始的字符索引位置
*/
while ((match = phoneRegex.exec(text)) !== null){
// 将字符偏移量转换为行列位置
/**
* 获取的数据是一个 vscode.Position 对象,包含:
{
line: 2, // 行号(从0开始)
character: 4 // 列号(从0开始,该行的字符偏移)
}
作用:将字符偏移量转换为行列坐标
例子:
文本内容:
第0行: "hello" (5个字符 + 换行符)
第1行: "world" (5个字符 + 换行符)
第2行: "联系我:13812345678"
如果 match.index = 16(假设)
document.positionAt(16) 会计算出:
- 这是在第2行
- 第2行的第4个字符位置
返回:Position { line: 2, character: 4 }
*/
const startPos = document.positionAt(match.index);
/**
* 计算得出:匹配字符串结束位置的 Position 对象
例子:
match.index = 4 // 起始位置
match[0] = "13812345678" // 长度11
match.index + match[0].length = 4 + 11 = 15
document.positionAt(15)
返回:Position { line: 2, character: 15 } // 结束位置
*/
const endPos = document.positionAt(match.index + match[0].length);
/**
* 作用:创建一个范围对象,表示代码中的一个区域
range = {
start: Position { line: 2, character: 4 }, // 起始位置
end: Position { line: 2, character: 15 } // 结束位置
}
用途:
- 告诉 VS Code 在哪里画波浪线(警告/错误标记)
- 指定高亮显示的区域
- 用于创建 Diagnostic 时指定问题的位置
返回 Range { start: {0,4}, end: {0,15} }
*/
const range = new vscode.Range(startPos,endPos);
const diagnostic = new vscode.Diagnostic(
range,
`检测到手机号指纹信息:${match[0]}`,
vscode.DiagnosticSeverity.Warning// 告警级别
);
diagnostics.push(diagnostic);
}
// 将诊断信息关联到文档
collection.set(document.uri, diagnostics);
}
exportfunctiondeactivate() {
// 清理资源(如果需要)
}
2.3 修改 package.json
将 "activationEvents": [] 修改为如下
// 启动成功后激活插件
"activationEvents":[
"onStartupFinished"
],
2.4 测试
-
1. 按 F5运行 -
2. 在新窗口中创建一个文件,输入: 我的电话是 13812345678 -
3. 你会看到手机号下面出现黄色波浪线

核心概念解释
const text = document.getText();
document.getText() 的含义
这个方法获取的是整个文件的所有文本内容,包括所有行和换行符。
举例:
假设你的文件内容是:
第1行: hello world
第2行: 我的手机号是 13812345678
第3行: 邮箱 test@example.com
那么 text 的值是:
"hello world\n我的手机号是 13812345678\n邮箱 test@example.com"
while 循环的工作方式
while((match = rule.pattern.exec(text)) !== null){
这个循环是在整个文档内容中全局搜索:
1. 第一次循环:在整个 text 中找到第一个匹配(比如手机号)
2. 第二次循环:从上次匹配位置之后继续找下一个匹配
3. 重复:直到找不到更多匹配为止
关键点
- ✅ text = 整个文档的所有内容
- ✅ rule.pattern.exec(text) = 在整个文档中搜索
- ❌ 不是逐行处理
- ❌ 不是每行的数据
这样可以一次性扫描整个文件中的所有敏感信息!
=======================================================================
const startPos = document.positionAt(match.index);
const endPos = document.positionAt(match.index + match[0].length);
步骤拆解
假设文档内容是:
第0行: hello world
第1行: 联系我 13812345678
第2行: bye
实际的 text 字符串是:
"hello world\n联系我 13812345678\nbye"
↑0 ↑11↑12 ↑16 ↑27↑28
当匹配到手机号时
1. 正则匹配:
match.index = 16 // 手机号在整个字符串中的起始位置
match[0] = "13812345678" // 匹配到的内容
2. document.positionAt(16) 做了什么?
- VS Code 内部知道每个换行符的位置
- 它计算:16 这个字符偏移量在哪一行?
- 发现:
- 第0行结束于位置 11(\n 之前)
- 第1行从位置 12 开始
- 位置 16 在第1行,距离行首 4 个字符
3. 返回位置对象:
startPos = { line: 1, character: 4 } // 第1行,第4列
关键点
- ✅ match.index 只是字符偏移量(整数)
- ✅ document.positionAt() 自动转换为 {line, character}
- ✅ VS Code 的 TextDocument 对象内部维护了换行符位置的索引
这就是为什么虽然你只有一个大字符串,但依然能精确获取行列位置的原因!document.positionAt() 帮你完成了所有计算。
API解释
|
|
|
|---|---|
vscode.languages.createDiagnosticCollection() |
|
vscode.workspace.onDidChangeTextDocument |
|
document.getText() |
|
document.positionAt(offset) |
|
vscode.Diagnostic |
|
collection.set(uri, diagnostics) |
|
核心流转图
┌────────────────────────────────────────────────────────────────┐
│ VS Code Editor │
│ 用户正在编辑的文件 │
└───────────────────────────┬────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
onDidOpenTextDocument onDidChangeTextDocument 手动命令
│ │ │
└───────────────┼───────────────┘
▼
document.getText()
获取文件全部文本
│
▼
┌─────────────────────────────┐
│ 正则匹配 / Python 扫描 │
│ 返回匹配结果列表 │
└─────────────┬───────────────┘
│
▼
┌─────────────────────────────┐
│ document.positionAt() │
│ 字符偏移 → 行列位置 │
└─────────────┬───────────────┘
│
▼
┌─────────────────────────────┐
│ 创建 vscode.Diagnostic │
│ - range: 位置范围 │
│ - message: 提示信息 │
│ - severity: 严重级别 │
└─────────────┬───────────────┘
│
▼
┌─────────────────────────────┐
│ collection.set(uri, [...])│
│ 关联诊断信息到文档 │
└─────────────┬───────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ VS Code UI │
│ - 编辑器中显示波浪线 │
│ - 问题面板显示列表 │
│ - 悬停显示详情 │
└────────────────────────────────────────────────────────────────┘
夜雨聆风
