如何編寫一個(gè)Vs?
本文邀請(qǐng)cheeqi來(lái)回答,讓他手把手教你如何開發(fā)一個(gè)爆款VS Code插件!
vscode 插件的形態(tài)和一個(gè) npm 包非常相似,需要在項(xiàng)目的根目錄添加 package.json,并且在其中增加一些 vscode 獨(dú)家的設(shè)置。其中最主要的設(shè)置是 Activation Events(插件的激活時(shí)機(jī)) 和 contribution points (插件的能力)。接下來(lái)我們主要看看這兩個(gè)配置具體是什么意思。
聲明插件的激活時(shí)機(jī) Activation Events我將 vscode 的生命周期簡(jiǎn)單描述為下圖。下面會(huì)做進(jìn)一步解釋。
[ vscode 插件生命周期(轉(zhuǎn)載請(qǐng)注明作者 cheeqi) ]
activate() 函數(shù) & deactivate() 函數(shù)
可以看到生命周期中最終要的兩個(gè)節(jié)點(diǎn)就是activate函數(shù)和deactivate函數(shù)。這兩個(gè)函數(shù)需要在插件 npm 模塊的入口文件 export 出去給 vscode 主動(dòng)調(diào)用。
其中,activate 會(huì)在 vscode 認(rèn)為合適的時(shí)機(jī)調(diào)用,并且在插件的運(yùn)行周期內(nèi)只調(diào)用一次。因此在 activate 函數(shù)中開始啟動(dòng)插件的邏輯,是一個(gè)非常合適的時(shí)機(jī)。
deactivate 函數(shù)會(huì)在插件卸載之前調(diào)用,如果你的卸載邏輯中存在異步操作,那么只需要在deactivate 函數(shù)中 retuen 一個(gè) promise 對(duì)象,vscode 會(huì)在 promise resolve 時(shí)才正式將插件卸載掉。
onXxxx Activation Events可以看到在activate函數(shù)之前,還有onLanguage等事件的描述,實(shí)際上這些就是聲明在插件 package.json 文件中的 Activation Events。聲明這些 Activation Events 后,vscode 就會(huì)在適當(dāng)?shù)臅r(shí)機(jī)回調(diào)插件中的 activate函數(shù)。vscode之所以這么設(shè)計(jì),是為了節(jié)省資源開銷,只在必要的時(shí)候才激活你的插件。當(dāng)然,如果你的插件非常重要,不希望在某個(gè)事件之后才被激活,你可以聲明Activation Events為*這樣 vscode 就會(huì)在啟動(dòng)的時(shí)候就開始回調(diào) activate函數(shù)。
插件的具體邏輯插件中的具體邏輯 vscode 沒(méi)有做任何限制,你可以通過(guò)調(diào)用vscdoe提供的各種 api 對(duì)其進(jìn)行擴(kuò)充。不過(guò)需要注意的是,出于性能和移植性考慮,vscode不允許開發(fā)者直接操作dom。
關(guān)于vscode 的 api 可以參考
https://code.visualstudio.com/api/references/vscode-api 這是微軟根據(jù) vscode 的 d.ts 文件生成的文檔
舉個(gè)例子接下來(lái)我們來(lái)看幾個(gè)插件的 Activation Events 聲明
超越鼓勵(lì)師 申明了 onCommand:ycy.showReminderView 和 * ,其實(shí)我們都知道只聲明后一個(gè)就足夠了
vuter 申明了 onLanguage:vue 所以他會(huì)在用戶打開 vue 語(yǔ)言文件時(shí)被激活
vscode-icons 是一個(gè)純主題插件,聲明的是 *
GitLens 需要覆蓋所有的文件,并且在vscode啟動(dòng)時(shí)就需要激活,他的聲明是 *
關(guān)于 Activation Events 的說(shuō)明可以參考官方文檔 https://code.visualstudio.com/api/references/activation-events
聲明插件的貢獻(xiàn)點(diǎn) contribution points
需要在 package.json 中聲明的另一個(gè)重要字段就是 contribution points。 contribution points描述了當(dāng)前插件支持哪些能力,以及對(duì)應(yīng)能力的配置。
由于 vscode 禁止直接操作dom,往 UI 中插入功能的正確方式是聲明貢獻(xiàn)點(diǎn)。下圖列出了 vscode 支持的所有貢獻(xiàn)點(diǎn)。
[ 目前 vscode 支持的貢獻(xiàn)點(diǎn) ]
舉個(gè)例子
接下來(lái)我們來(lái)看幾個(gè)插件的 contribution points 聲明
超越鼓勵(lì)師 支持通過(guò) commands 觸發(fā)楊超越的提醒,同時(shí)可以配置提醒出現(xiàn)的時(shí)機(jī),因此包括 commands / configuration
vuter 主要為 vue 文件提供語(yǔ)言支持,可以看到他提供的 contribution points 比較廣,包括 commands / breakpoints / languages / grammars / configuration
vscode-icons 已支持主題為主,他提供了 iconThemes / commands / configuration
GitLens 是對(duì)vscode git 功能的增強(qiáng),所以他的插入點(diǎn)集中在 UI 上的能力 configuration / commands / menus /resourceLabelFormatters / viewsContainers / views
關(guān)于 contribution points 的更多說(shuō)明可以參考 https://code.visualstudio.com/api/references/contribution-points
編程語(yǔ)言支持那么,要怎么給 vscode 增加一門新的編程語(yǔ)言支持呢?
就像之前說(shuō)的,vscode 主要支持兩類編程語(yǔ)言支持: 聲明類語(yǔ)言特性主要描述了代碼高亮、代碼片段等輕量級(jí)需要實(shí)時(shí)給出響應(yīng)的語(yǔ)言特性支持;而程序類語(yǔ)言特性只要提供更加高級(jí)的跳到定義、查找引用、hover提示等對(duì)實(shí)時(shí)性要求不高,而且需要大量計(jì)算的語(yǔ)言能力。因此前者更加適合在 IDE 的主線程進(jìn)行處理,而后者可以考慮拆分到其他線程甚至服務(wù)中進(jìn)行計(jì)算。
聲明類語(yǔ)言特性(基本支持)
下面主要以語(yǔ)法高亮為例子介紹聲明式語(yǔ)言支持。
[ 從手寫 paser 到 TextMate ]
在最初,微軟的工程師們?yōu)閣eb開發(fā)中常見的開發(fā)語(yǔ)言都手寫了 paser。這類 paser 執(zhí)行效率很高,但對(duì)開發(fā)者的能力要求也比較高,不太適合未來(lái)的插件擴(kuò)展。從 vscode 1.8 版本開始,微軟引入了 TextMate 的高亮語(yǔ)法,并逐步將原有的手寫 paser 切換到這種語(yǔ)法上。
[ TextMate 官網(wǎng) ]
TextMate 本身是 mac 下的一個(gè)文本編輯器,vscode 借用了他對(duì)語(yǔ)言高亮文本的定義方式。TextMate語(yǔ)法的本質(zhì)是用一個(gè) json 文件來(lái)描述語(yǔ)言中的 token 和結(jié)構(gòu),當(dāng)然為了方便,也可以改用 YAML 并編譯成json。
順便一提,而 TextMate 語(yǔ)法使用的是 oniguruma 庫(kù)來(lái)解析正則表達(dá)式,oniguruma 中支持一些 js 引擎目前還不支持的正則特性,因此在 vscode 中使用了一個(gè) oniguruma 的 c++ 模塊來(lái)加速正則表達(dá)式解析速度。
另外,為了方便開發(fā)者編寫語(yǔ)法高亮插件,vscode還提供了一個(gè) yomen 模板用于生成插件基本目錄結(jié)構(gòu),以及一個(gè)名為 inspectTMScopes 的調(diào)試器查看詞法分析的結(jié)果。
[ vscode 提供的 yomen 模板 ]
[ inspectTMScopes ]
除了語(yǔ)法高亮外,vscode還支持這些特性:注釋切換、括號(hào)定義、自動(dòng)閉合、Auto surrounding、代碼折疊、word Pattern、縮進(jìn)規(guī)則等,詳見
https://code.visualstudio.com/api/language-extensions/language-configuration-guide