本篇文章帶大家一起來寫一個vscode翻譯插件,通過實(shí)現(xiàn)一個翻譯插件實(shí)例的方式來熟悉 VS Code 插件開發(fā)的常見功能和方法,希望對需要的朋友有所幫助!
本文將通過實(shí)現(xiàn)一個翻譯插件實(shí)例的方式來熟悉 VS Code 插件開發(fā)的常見功能和方法。當(dāng)然大家可以前往 VS Code 官網(wǎng)API 和官方 GitHub 示例 查看和學(xué)習(xí)?!就扑]學(xué)習(xí):《vscode入門教程》】
需求
對應(yīng)程序員來說,翻譯是個很常見的需求,尤其像我這樣一個英語不好的程序員。
-
可以直接替換翻譯中文為變量名
-
劃詞翻譯,用于源碼中的注釋翻譯
開發(fā)
初始化項(xiàng)目
執(zhí)行腳手架,初始化項(xiàng)目
yo code
hello world
創(chuàng)建好目錄后,我們可以到入口文件找到入口文件 ./src/extension.ts
中有個 active
方法
export function activate(context: vscode.ExtensionContext) { console.log('Congratulations, your extension "vscode-fanyi" is now active!'); let disposable = vscode.commands.registerCommand( "vscode-fanyi.helloWorld", () => { vscode.window.showInformationMessage("Hello World from vscode-fanyi!"); } ); context.subscriptions.push(disposable); }
active 方法是插件的入口方法,注冊了一個 vscode-fanyi.helloWorld
方法
"activationEvents": [ "onCommand:vscode-fanyi.helloWorld" ], "contributes": { "commands": [ { "command": "vscode-fanyi.helloWorld", "title": "Hello World" } ] }
然后在 package.json
中配置了激活的事件,和執(zhí)行事件的標(biāo)題是 Hello World
按 F5
調(diào)試, 就會自動打開一個新的 vscode 擴(kuò)展調(diào)試窗口,執(zhí)行命令就可以看下如下效果。
翻譯API
翻譯api 我這邊選擇使用 有道智能云,當(dāng)然大家可以選擇其他翻譯API,選擇它的原因是因?yàn)椋鹤跃陀?00元的免費(fèi)體驗(yàn)金,對于個人使用完全足夠了。
首先創(chuàng)建一個應(yīng)用,選擇服務(wù)為自然語言翻譯服務(wù),接入方式為API
創(chuàng)建完成后可以獲得應(yīng)用ID和秘鑰。
根據(jù)官方 JS demo 改成 Nodejs 版本
import CryptoJS from "crypto-js"; import axios from "axios"; import querystring from "querystring"; function truncate(q: string): string { var len = q.length; if (len <= 20) { return q; } return q.substring(0, 10) + len + q.substring(len - 10, len); } async function youdao(query: string) { var appKey = "3dde97353116e9bf"; var key = "xxxxxxxxxx"; //注意:暴露appSecret,有被盜用造成損失的風(fēng)險 var salt = new Date().getTime(); var curtime = Math.round(new Date().getTime() / 1000); // 多個query可以用n連接 如 query='applenorangenbanananpear' var from = "AUTO"; var to = "AUTO"; var str1 = appKey + truncate(query) + salt + curtime + key; var sign = CryptoJS.SHA256(str1).toString(CryptoJS.enc.Hex); const res = await axios.post( "http://openapi.youdao.com/api", querystring.stringify({ q: query, appKey, salt, from, to, sign, signType: "v3", curtime, }) ); return res.data; }
首先要安裝這3個包,其中 crypto-js
生成簽名,axios
Nodejs 請求庫。
安裝
yarn add crypto-js axios querystring
查詢結(jié)果
如果正確一定存在 translation 中
{ "errorCode":"0", "query":"good", //查詢正確時,一定存在 "translation": [ //查詢正確時一定存在 "好" ], "basic":{ // 有道詞典-基本詞典,查詞時才有 "phonetic":"g?d", "uk-phonetic":"g?d", //英式音標(biāo) "us-phonetic":"ɡ?d", //美式音標(biāo) "uk-speech": "XXXX",//英式發(fā)音 "us-speech": "XXXX",//美式發(fā)音 "explains":[ "好處", "好的", "好", ] }, }
然后更改注冊事件為異步返回
let disposable = vscode.commands.registerCommand( "vscode-fanyi.helloWorld", async () => { const res = await youdao( 'Congratulations, your extension "vscode-fanyi" is now active!' ); vscode.window.showInformationMessage(res.translation[0]); } ); context.subscriptions.push(disposable);
來看下調(diào)試結(jié)果
劃詞替換
先獲取選擇文本, 然后翻譯,最后翻譯完成后替換原來文本。
export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.commands.registerCommand("vscode-fanyi.replace", async () => { let editor = vscode.window.activeTextEditor; if (!editor) { return; // No open text editor } let selection = editor.selection; let text = editor.document.getText(selection);//選擇文本 //有選中翻譯選中的詞 if (text.length) { const res = await youdao(text); //vscode.window.showInformationMessage(res.translation[0]); editor.edit((builder) => { builder.replace(selection, res.translation[0]);//替換選中文本 }); } }) ); }
跟新下 package.json 中的配置
"activationEvents": [ "onCommand:vscode-fanyi.replace" ], "contributes": { "commands": [ { "command": "vscode-fanyi.replace", "title": "翻譯" } ], "keybindings": [ { "command": "vscode-fanyi.replace", "key": "ctrl+t", "mac": "cmd+t", "when": "editorTextFocus" } ], "menus": { "editor/context": [ { "when": "editorTextFocus", "command": "vscode-fanyi.replace", "group": "vscode-fanyi" } ] } },
新增一個右鍵菜單,綁定鍵盤快捷鍵.
下圖是vscode 官方菜單分組,將分組放在修改代碼部分
一起來看下效果
劃詞翻譯
VS code 提供一個 provideHover 當(dāng)鼠標(biāo)移動在上面的時候就可以根據(jù)當(dāng)前的單詞做一些具體操作,但是這個翻譯的場景下,單個單詞不夠,所以要根據(jù)選中的詞來翻譯。一起來看下代碼吧。
vscode.languages.registerHoverProvider("*", { async provideHover(document, position, token) { const editor = vscode.window.activeTextEditor; if (!editor) { return; // No open text editor } const selection = editor.selection; const text = document.getText(selection); const res = await youdao(text); const markdownString = new vscode.MarkdownString(); markdownString.appendMarkdown( `#### 翻譯 nn ${res.translation[0]} nn` ); if (res.basic) { markdownString.appendMarkdown( `**美** ${res.basic["us-phonetic"]} **英** ${res.basic["uk-phonetic"]} nn` ); if (res.basic.explains) { res.basic.explains.forEach((w: string) => { markdownString.appendMarkdown(`${w} nn`); }); } } if (res.web) { markdownString.appendMarkdown(`#### 網(wǎng)絡(luò)釋義 nn`); res.web.forEach((w: Word) => { markdownString.appendMarkdown( `**${w.key}:** ${String(w.value).toString()} nn` ); }); } markdownString.supportHtml = true; markdownString.isTrusted = true; return new vscode.Hover(markdownString); }, });
本來想 MarkdownString 如果支持 html 的話, 可以把翻譯結(jié)果的音頻也放到里面,奈何不支持,不知道有沒有小伙伴做過類似的功能,可以在評論區(qū)交流。
最關(guān)鍵的一步,需要在 package.json
中更改 activationEvents
為 "=onStartupFinished
,這一點(diǎn)可以在文檔中找到.
此激活事件將被發(fā)出,并且相關(guān)擴(kuò)展將在VS代碼啟動后的某個時間被激活。這類似于激活事件,但不會降低VS代碼啟動的速度。當(dāng)前,此事件在所有激活的擴(kuò)展完成激活后發(fā)出。
"activationEvents": [ "onStartupFinished" ],
效果
駝峰轉(zhuǎn)換
如果是變量是駝峰命名,可能無法翻譯,需要轉(zhuǎn)換下成空格
function changeWord(text: string): string { if (!text.includes(" ") && text.match(/[A-Z]/)) { const str = text.replace(/([A-Z])/g, " $1"); let value = str.substr(0, 1).toUpperCase() + str.substr(1); return value; } return text; }
自定義配置
將有道 appKey 和 appSecret 改成用戶擴(kuò)展配置, 在下 package.json
中的配置 contributes
添加 configuration
配置
"configuration": { "title": "Vscode fanyi", "type": "object", "properties": { "vscodeFanyi.youdaoApiname": { "type": "string", "description": "youdao appKey" }, "vscodeFanyi.youdaoApikey": { "type": "string", "description": "youdao appSecret" }, } }
就可以在擴(kuò)展下方填入配置了
然后在代碼中 獲得配置,并傳入到原先的翻譯函數(shù)中就可以了
const config = vscode.workspace.getConfiguration("vscodeFanyi"); const appKey = config.get("youdaoAppkey") as string; const appSecret = config.get("youdaoAppSecret") as string;
小結(jié)
本插件與 comment-translate 對比
1、API 不同
-
本插件目前只支持有道,用完免費(fèi)相當(dāng)于是付費(fèi)
-
comment-translate 支持百度谷歌和必應(yīng),是免費(fèi)API
2、實(shí)現(xiàn)方式不同
-
本插件是利用 provideHover 劃詞翻譯,實(shí)現(xiàn)起來比較簡單
-
comment-translate 是hover 翻譯,使用 Language Server Extension Guide 實(shí)現(xiàn)起來比較復(fù)雜
最后附上鏈接和github
vscode 使用范圍在擴(kuò)大,從extensions market 市場上也可以發(fā)現(xiàn),各種功能的插件基本都很齊全。本篇只介紹了其功能的冰山一角,同時 vscode extensions 開發(fā)門檻不高,歡迎大家嘗試,或者將有意思的 extensions 推薦在評論區(qū)。
希望這篇文章對大家有所幫助,也可以參考我往期的文章或者在評論區(qū)交流你的想法和心得,歡迎一起探索前端。