VsCode插件開發(fā)-01 基礎(chǔ)開發(fā)入門
1 前置準備
1.1 安裝腳手架工具
npm install -g yo generator-code
1.2 創(chuàng)建項目
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 項目結(jié)構(gòu)
生成后的關(guān)鍵文件:
sensitive-scanner/
├── src/
│ ? └── extension.ts ? ?# 插件入口(主要編寫代碼的地方)
├── package.json ? ? ? ?# 插件配置(聲明命令、配置項等)
└── tsconfig.json ? ? ? # TypeScript 配置
1.4 運行和調(diào)試
-
1. 用 VS Code 打開項目 -
2. 按? F5?啟動調(diào)試 -
3. 會打開一個新的 VS Code 窗口(擴展開發(fā)宿主) -
4. 在新窗口中測試你的插件
2 最簡單的掃描器
目標:檢測文件中的手機號碼,用波浪線標記出來。
2.1 理解核心概念
用戶編輯文件 → 插件獲取文件內(nèi)容 → 正則匹配 → 創(chuàng)建診斷信息 → 顯示在編輯器中
2.2 修改 extension.ts
刪除默認生成的代碼,替換為:
import?*?as?vscode?from'vscode';
exportfunctionactivate(context: vscode.ExtensionContext){
console.log("指紋清除掃描器已激活");
// 創(chuàng)建診斷集合,這邊是vscode自帶的API
const?diagnosticCollection = vscode.languages.createDiagnosticCollection("test-scanner");
// 監(jiān)聽文檔變化事件,vscode自帶
vscode.workspace.onDidChangeTextDocument(event?=>?{
scanDocument(event.document,diagnosticCollection);
});
// 監(jiān)聽文檔打開事件,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
?* - 表示要掃描的文檔對象
?* ?- 包含文檔的文本內(nèi)容、文件路徑、語言類型等信息
?* 2. collection: vscode.DiagnosticCollection
?* ?- 診斷集合,用于存儲和顯示代碼問題
?* ?- 可以在 VS Code 的"問題"面板中顯示警告、錯誤等信息(就像 ESLint 或 TypeScript 顯示的那些紅色/黃色波浪線)
?*?@param?document?
?*?@param?collection?
?*/
functionscanDocument(document: vscode.TextDocument,collection: vscode.DiagnosticCollection){
// 獲取文檔的全部內(nèi)容
const?text =?document.getText();
// 簡單的手機號正則
const?phoneRegex =?/1[3-9]\d{9}/g;
// 用于臨時存儲在當前文檔中發(fā)現(xiàn)的所有問題
constdiagnostics: vscode.Diagnostic[] = [];
let?match;
// 遍歷所有信息進行匹配
/**
? ?match 拿到的數(shù)據(jù)是一個數(shù)組(如果匹配成功)或 null(如果沒有匹配)。
? ?假設(shè)文本是:"聯(lián)系我:13812345678",正則匹配到手機號,match 會是:
match = [
'13812345678', ?// match[0]: 完整匹配的字符串
// match[1], match[2]... 如果有捕獲組,會在這里
]
// match 還有額外屬性:
match.index = 4 ? // 匹配開始的位置(字符偏移量)
match.input = "聯(lián)系我:13812345678" ?// 原始文本
關(guān)鍵點:
- match[0] = 匹配到的完整字符串
- match.index = 匹配開始的字符索引位置
*/
while?((match = phoneRegex.exec(text)) !==?null){
// 將字符偏移量轉(zhuǎn)換為行列位置
/**
* ?獲取的數(shù)據(jù)是一個 vscode.Position 對象,包含:
{
line: 2, ? ? ? ?// 行號(從0開始)
character: 4 ? ?// 列號(從0開始,該行的字符偏移)
}
作用:將字符偏移量轉(zhuǎn)換為行列坐標
例子:
文本內(nèi)容:
第0行: "hello" ? ? ? ?(5個字符 + 換行符)
第1行: "world" ? ? ? ?(5個字符 + 換行符)
第2行: "聯(lián)系我:13812345678"
如果 match.index = 16(假設(shè))
document.positionAt(16) 會計算出:
- 這是在第2行
- 第2行的第4個字符位置
返回:Position { line: 2, character: 4 }
*/
const?startPos =?document.positionAt(match.index);
/**
* ?計算得出:匹配字符串結(jié)束位置的 Position 對象
例子:
match.index = 4 ? ? ? ? ? ? ?// 起始位置
match[0] = "13812345678" ? ? // 長度11
match.index + match[0].length = 4 + 11 = 15
document.positionAt(15)?
返回:Position { line: 2, character: 15 } ?// 結(jié)束位置
*/
const?endPos =?document.positionAt(match.index?+ match[0].length);
/**
* ?作用:創(chuàng)建一個范圍對象,表示代碼中的一個區(qū)域
range = {
start: Position { line: 2, character: 4 }, ? // 起始位置
end: Position { line: 2, character: 15 } ? ? ?// 結(jié)束位置
}
用途:
- 告訴 VS Code 在哪里畫波浪線(警告/錯誤標記)
- 指定高亮顯示的區(qū)域
- 用于創(chuàng)建 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);
}
// 將診斷信息關(guān)聯(lián)到文檔
? ? collection.set(document.uri, diagnostics);
}
exportfunctiondeactivate() {
// 清理資源(如果需要)
}
2.3 修改 package.json
將?"activationEvents": []?修改為如下
// 啟動成功后激活插件
"activationEvents":[
"onStartupFinished"
],
2.4 測試
-
1. 按? F5?運行 -
2. 在新窗口中創(chuàng)建一個文件,輸入: 我的電話是 13812345678 -
3. 你會看到手機號下面出現(xiàn)黃色波浪線

核心概念解釋
const text = document.getText();
? document.getText() 的含義
? 這個方法獲取的是整個文件的所有文本內(nèi)容,包括所有行和換行符。
? 舉例:
? 假設(shè)你的文件內(nèi)容是:
? 第1行: hello world
? 第2行: 我的手機號是 13812345678
? 第3行: 郵箱 [email protected]
? 那么 text 的值是:
? "hello world\n我的手機號是 13812345678\n郵箱 [email protected]"
? while 循環(huán)的工作方式
? while((match = rule.pattern.exec(text)) !== null){
? 這個循環(huán)是在整個文檔內(nèi)容中全局搜索:
? 1. 第一次循環(huán):在整個 text 中找到第一個匹配(比如手機號)
? 2. 第二次循環(huán):從上次匹配位置之后繼續(xù)找下一個匹配
? 3. 重復:直到找不到更多匹配為止
? 關(guān)鍵點
? - ? text = 整個文檔的所有內(nèi)容
? - ? rule.pattern.exec(text) = 在整個文檔中搜索
? - ? 不是逐行處理
? - ? 不是每行的數(shù)據(jù)
? 這樣可以一次性掃描整個文件中的所有敏感信息!
=======================================================================
const startPos = document.positionAt(match.index);
const endPos = document.positionAt(match.index + match[0].length);
? 步驟拆解
? 假設(shè)文檔內(nèi)容是:
? 第0行: hello world
? 第1行: 聯(lián)系我 13812345678
? 第2行: bye
? 實際的 text 字符串是:
? "hello world\n聯(lián)系我 13812345678\nbye"
? ? ↑0 ? ? ? ?↑11↑12 ? ↑16 ? ? ? ? ?↑27↑28
? 當匹配到手機號時
? 1. 正則匹配:
? match.index = 16 ? ? ? ? ? // 手機號在整個字符串中的起始位置
? match[0] = "13812345678" ? // 匹配到的內(nèi)容
? 2. document.positionAt(16) 做了什么?
? ? - VS Code 內(nèi)部知道每個換行符的位置
? ? - 它計算:16 這個字符偏移量在哪一行?
? ? - 發(fā)現(xiàn):
? ? ? ? - 第0行結(jié)束于位置 11(\n 之前)
? ? ? - 第1行從位置 12 開始
? ? ? - 位置 16 在第1行,距離行首 4 個字符
? 3. 返回位置對象:
? startPos = { line: 1, character: 4 } ?// 第1行,第4列
? 關(guān)鍵點
? - ? match.index 只是字符偏移量(整數(shù))
? - ? document.positionAt() 自動轉(zhuǎn)換為 {line, character}
? - ? VS Code 的 TextDocument 對象內(nèi)部維護了換行符位置的索引
? 這就是為什么雖然你只有一個大字符串,但依然能精確獲取行列位置的原因!document.positionAt() 幫你完成了所有計算。
API解釋
|
|
|
|---|---|
vscode.languages.createDiagnosticCollection() |
|
vscode.workspace.onDidChangeTextDocument |
|
document.getText() |
|
document.positionAt(offset) |
|
vscode.Diagnostic |
|
collection.set(uri, diagnostics) |
|
核心流轉(zhuǎn)圖
┌────────────────────────────────────────────────────────────────┐
│ ? ? ? ? ? ? ? ? ? ? VS Code Editor ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? ? ? ? ? ? ? ? ? 用戶正在編輯的文件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
└───────────────────────────┬────────────────────────────────────┘
? ? ? ? ? ? ? ? ? ? ? ? ? ? │
? ? ? ? ? ? ┌───────────────┼───────────────┐
? ? ? ? ? ? ▼ ? ? ? ? ? ? ? ▼ ? ? ? ? ? ? ? ▼
? ?onDidOpenTextDocument ? onDidChangeTextDocument ? 手動命令
? ? ? ? ? ? │ ? ? ? ? ? ? ? │ ? ? ? ? ? ? ? │
? ? ? ? ? ? └───────────────┼───────────────┘
? ? ? ? ? ? ? ? ? ? ? ? ? ? ▼
? ? ? ? ? ? ? ? ? ? document.getText()
? ? ? ? ? ? ? ? ? ? 獲取文件全部文本
? ? ? ? ? ? ? ? ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ▼
? ? ? ? ? ? ? ┌─────────────────────────────┐
? ? ? ? ? ? ? │ ? ? 正則匹配 / Python 掃描 ? │
? ? ? ? ? ? ? │ ? ? 返回匹配結(jié)果列表 ? ? ? ? │
? ? ? ? ? ? ? └─────────────┬───────────────┘
? ? ? ? ? ? ? ? ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ▼
? ? ? ? ? ? ? ┌─────────────────────────────┐
? ? ? ? ? ? ? │ ? document.positionAt() ? ? │
? ? ? ? ? ? ? │ ? 字符偏移 → 行列位置 ? ? ? ?│
? ? ? ? ? ? ? └─────────────┬───────────────┘
? ? ? ? ? ? ? ? ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ▼
? ? ? ? ? ? ? ┌─────────────────────────────┐
? ? ? ? ? ? ? │ ? 創(chuàng)建 vscode.Diagnostic ? ?│
? ? ? ? ? ? ? │ ? - range: 位置范圍 ? ? ? ? ?│
? ? ? ? ? ? ? │ ? - message: 提示信息 ? ? ? ?│
? ? ? ? ? ? ? │ ? - severity: 嚴重級別 ? ? ? │
? ? ? ? ? ? ? └─────────────┬───────────────┘
? ? ? ? ? ? ? ? ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ▼
? ? ? ? ? ? ? ┌─────────────────────────────┐
? ? ? ? ? ? ? │ ? collection.set(uri, [...])│
? ? ? ? ? ? ? │ ? 關(guān)聯(lián)診斷信息到文檔 ? ? ? ? │
? ? ? ? ? ? ? └─────────────┬───────────────┘
? ? ? ? ? ? ? ? ? ? ? ? ? ? │
? ? ? ? ? ? ? ? ? ? ? ? ? ? ▼
┌────────────────────────────────────────────────────────────────┐
│ ? ? ? ? ? ? ? ? ? ? VS Code UI ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?│
│ ? - 編輯器中顯示波浪線 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
│ ? - 問題面板顯示列表 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
│ ? - 懸停顯示詳情 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │
└────────────────────────────────────────────────────────────────┘
夜雨聆風
