這篇文章帶大家從0開發一個vscode變數翻譯插件,本文會從四個面向來完整的展示整個插件從功能設計到發布的完整歷程,希望對大家有所幫助!
需求的起因是英文渣在開發的過程中經常遇到一個變數知道中文叫啥,但是英文單字可能就忘了,或者不知道,這個時候,我之前做法是打開瀏覽器,打開谷歌翻譯,輸入中文,複製英文,然後切回vscode,貼上結果。
實在是太麻煩了,年輕的時候還好,記性好,英文單字大部分都能記住,但隨著年紀越來越大,頭髮越來越少,記性也是越來越差,上面的步驟重複的次數也越來越多,所以痛定思痛,就開發了這款外掛。
因為自己也是這幾天從零開始學習的插件開發,所以本文完全的記錄了一個小白開發的插件開發之路,內容主要是實戰類的介紹,主要從四個方面介紹來完整的展示整個插件從功能設計到發布的完整歷程。
功能設計
環境建置
外掛功能開發
#外掛程式打包發布
【推薦學習:《vscode入門教學》】
功能設計
功能主要是兩個功能,中譯英,其他語言翻譯成中文
#將中文變數替換為翻譯後的英文變量,多個單字需要自動駝峰,解決的場景就是日常開發經常碰到的「英文卡殼」
#劃詞翻譯,自動將各種語言翻譯成中文,這解決的場景是有時候看國外專案原始碼的註解碰到不會的單字不知道啥意思影響效率
#環境建置
上手的第一步,環境建構
-
安裝鷹架, yo 與generator-code,這兩個工具可以幫助我們快速建立項目,詳情可見(https://github .com/Microsoft/vscode-generator-code)
//安装 yarn global add yo generator-code
-
#安裝vsce,vsce可用於將開發的程式碼打包成.vsix後綴的文件,方便上傳至微軟插件商店或本地安裝
yarn global add vsce
-
產生並初始化項目,初始化資訊根據自己情況填寫
//初始化生成项目 yo code
到這一步後,選擇直接打開,Open with code
開啟後會自動建立一個工作區,並產生這些文件,可依自己需求對文件進行刪減,完成這一步後,我們可以直接進行開發與調試了
如何調試?
去運行與調試面板點擊Run Extention,或者快捷鍵F5,mac可以直接點擊觸控列的調試按鈕
打開後會彈出一個新的vscode窗口,這個新的窗口就是你的測試環境(擴展開發宿主),你做的外掛程式功能就是在這個新的視窗測試,列印的訊息在前一個視窗的偵錯控制台中,例如自帶的例子,在我們新視窗cmd/ctrl shift p後輸入Hello world後會在前一個視窗的控制台列印一些資訊
到這裡,開發準備環境就準備好了,下一步就是開始正式的外掛功能開發
外掛功能開發
外掛程式開發中,有兩個重要的文件,一個是package.json ,一個是extention.js
重要檔案說明
##package.json
- ##activationEvents
用來註冊啟動事件,用來表示在什麼情況下會啟動extention.js中的active函式。常見的有onLanguage,onCommand...更多資訊可查看vscode文檔activationEvents(https://code.visualstudio.com/api/references/activation-events)
- main
表示外掛程式的主入口
contributes用来注册命令(commands),绑定快捷键(keybindings),**配置设置项(configuration)**等等,更多可配置项可看文档(https://code.visualstudio.com/api/references/contribution-points)
extention.js
extention.js主要作用是作为插件功能的实现点,通过active,deactive函数,以及vscode提供的api以及一些事件钩子来完成插件功能的开发
实现翻译功能
翻译这里主要是使用了两个服务,谷歌和百度翻译。
谷歌翻译参考了别人的做法,使用google-translate-token获取到token,然后构造请求url,再处理返回的body,拿到返回结果。这里还有一个没搞懂的地方就是请求url的生成很迷,不知道这一块是啥意思。
const qs = require('querystring'); const got = require('got'); const safeEval = require('safe-eval'); const googleToken = require('google-translate-token'); const languages = require('../utils/languages.js'); const config = require('../config/index.js'); // 获取请求url async function getRequestUrl(text, opts) { let token = await googleToken.get(text); const data = { client: 'gtx', sl: opts.from, tl: opts.to, hl: opts.to, dt: ['at', 'bd', 'ex', 'ld', 'md', 'qca', 'rw', 'rm', 'ss', 't'], ie: 'UTF-8', oe: 'UTF-8', otf: 1, ssel: 0, tsel: 0, kc: 7, q: text }; data[token.name] = token.value; const requestUrl = `${config.googleBaseUrl}${qs.stringify(data)}`; return requestUrl; } //处理返回的body async function handleBody(url, opts) { const result = await got(url); let resultObj = { text: '', from: { language: { didYouMean: false, iso: '' }, text: { autoCorrected: false, value: '', didYouMean: false } }, raw: '' }; if (opts.raw) { resultObj.raw = result.body; } const body = safeEval(result.body); // console.log('body', body); body[0].forEach(function(obj) { if (obj[0]) { resultObj.text += obj[0]; } }); if (body[2] === body[8][0][0]) { resultObj.from.language.iso = body[2]; } else { resultObj.from.language.didYouMean = true; resultObj.from.language.iso = body[8][0][0]; } if (body[7] && body[7][0]) { let str = body[7][0]; str = str.replace(/<b><i>/g, '['); str = str.replace(/<\/i><\/b>/g, ']'); resultObj.from.text.value = str; if (body[7][5] === true) { resultObj.from.text.autoCorrected = true; } else { resultObj.from.text.didYouMean = true; } } return resultObj; } //翻译 async function translate(text, opts) { opts = opts || {}; opts.from = opts.from || 'auto'; opts.to = opts.to || 'en'; opts.from = languages.getCode(opts.from); opts.to = languages.getCode(opts.to); try { const requestUrl = await getRequestUrl(text, opts); const result = await handleBody(requestUrl, opts); return result; } catch (error) { console.log(error); } } // 获取翻译结果 const getGoogleTransResult = async(originText, ops = {}) => { const { from, to } = ops; try { const result = await translate(originText, { from: from || config.defaultFrom, to: to || defaultTo }); console.log('谷歌翻译结果', result.text); return result; } catch (error) { console.log(error); console.log('翻译失败'); } } module.exports = getGoogleTransResult;
百度翻译,百度翻译的比较简单,申请服务,获得appid和key,然后构造请求url直接请求就行
不知道如何申请的,可查看我之前的一篇文章 Electron+Vue从零开始打造一个本地文件翻译器 进行申请
https://juejin.cn/post/6899581622471884813
const md5 = require("md5"); const axios = require("axios"); const config = require('../config/index.js'); axios.defaults.withCredentials = true; axios.defaults.crossDomain = true; axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; // 百度翻译 async function getBaiduTransResult(text = "", opt = {}) { const { from, to, appid, key } = opt; try { const q = text; const salt = parseInt(Math.random() * 1000000000); let str = `${appid}${q}${salt}${key}`; const sign = md5(str); const query = encodeURI(q); const params = `q=${query}&from=${from}&to=${to}&appid=${appid}&salt=${salt}&sign=${sign}`; const url = `${config.baiduBaseUrl}${params}`; console.log(url); const res = await axios.get(url); console.log('百度翻译结果', res.data.trans_result[0]); return res.data.trans_result[0]; } catch (error) { console.log({ error }); } } module.exports = getBaiduTransResult;
获取选中的文本
使用事件钩子onDidChangeTextEditorSelection,获取选中的文本
onDidChangeTextEditorSelection(({ textEditor, selections }) => { text = textEditor.document.getText(selections[0]); })
配置项的获取更新
通过vscode.workspace.getConfiguration获取到工作区的配置项,然后通过事件钩子onDidChangeConfiguration监听配置项的变动。
获取更新配置项
const { getConfiguration } = vscode.workspace; const config = getConfiguration(); //注意get里面的参数其实就是package.json配置项里面的contributes.configuration.properties.xxx const isCopy = config.get(IS_COPY); const isReplace = config.get(IS_REPLACE); const isHump = config.get(IS_HUMP); const service = config.get(SERVICE); const baiduAppid = config.get(BAIDU_APPID); const baiduKey = config.get(BAIDU_KEY); //更新使用update方法,第三个参数为true代表应用到全局 config.update(SERVICE, selectedItem, true);
监听配置项的变动
const { getConfiguration, onDidChangeConfiguration } = vscode.workspace; const config = getConfiguration(); //监听变动 const disposeConfig = onDidChangeConfiguration(() => { config = getConfiguration(); })
监听个别配置项的变动
const disposeConfig = onDidChangeConfiguration((e) => { if (e && e.affectsConfiguration(BAIDU_KEY)) { //干些什么 } })
获取当前打开的编辑器对象
vscode.window.activeTextEditor代表当前打开的编辑器,如果切换标签页,而没有设置监听,那么这个这个对象不会自动更新,所以需要使用onDidChangeActiveTextEditor来监听,并替换之前的编辑器对象
const { activeTextEditor, onDidChangeActiveTextEditor } = vscode.window; let active = activeTextEditor; const edit = onDidChangeActiveTextEditor((textEditor) => { console.log('activeEditor改变了'); //更换打开的编辑器对象 if (textEditor) { active = textEditor; } })
划词翻译悬浮提示
通过vscode.languages.registerHoverProvider注册一个Hover,然后通过activeTextEditor拿到选中的词语进行翻译,然后再通过new vscode.Hover将翻译结果悬浮提示
// 划词翻译检测 const disposeHover = vscode.languages.registerHoverProvider("*", { async provideHover(document, position, token) { const service = config.get(SERVICE); const baiduAppid = config.get(BAIDU_APPID); const baiduKey = config.get(BAIDU_KEY); let response, responseText; const selected = document.getText(active.selection); // 谷歌翻译 if (service === 'google') { response = await getGoogleTransResult(selected, { from: 'auto', to: 'zh-cn' }); responseText = response.text; } // 百度翻译 if (service === 'baidu') { response = await getBaiduTransResult(selected, { from: "auto", to: "zh", appid: baiduAppid, key: baiduKey }); responseText = response.dst; } // 悬浮提示 return new vscode.Hover(`${responseText}`); } })
替换选中的文本
获取到activeTextEditor,调用他的edit方法,然后使用回调中的replace
//是否替换原文 if (isReplace) { let selectedItem = active.selection; active.edit(editBuilder => { editBuilder.replace(selectedItem, result) }) }
复制到剪贴板
使用vscode.env.clipboard.writeText;
// 是否复制翻译结果 if (isCopy) { vscode.env.clipboard.writeText(result); }
驼峰处理
function toHump(str) { if (!str) { return } const strArray = str.split(' '); const firstLetter = [strArray.shift()]; const newArray = strArray.map(item => { return `${item.substring(0,1).toUpperCase()}${item.substring(1)}`; }) const result = firstLetter.concat(newArray).join(''); return result; } module.exports = toHump;
快捷键绑定
通过vscode.commands.registerCommand注册绑定之前package.json中设置的keybindings,需要注意的是registerCommand的第一个参数需要与keybindings的command保持一致才能绑定
registerCommand('translateVariable.toEN', async() => { //do something }) //package.json "keybindings": [{ "key": "ctrl+t", "mac": "cmd+t", "when": "editorTextFocus", "command": "translateVariable.toEN" }],
插件打包发布
打包
vsce package
打包后会在目录下生成.vsix后缀的插件
发布
插件发布主要是把打包的vsix后缀插件,传入微软vscode插件商店,当然也能本地安装使用。
传入商店
发布到线上需要到 微软插件商店管理页面(https://marketplace.visualstudio.com/manage/createpublisher),创建发布者信息,如果没有微软账号,需要去申请。
创建完成后,选择发布到vscode商店
本地安装
本地是可以直接安装.vsix后缀插件的,找到插件菜单
选择从VSIX安装,安装上面打包的插件就好了
最後
vscode的中文資料有點少,這次開發大多數時間都在看英文文檔,以及上外網尋找資料,真的英語太重要了,後面多學點英文了,希望後面我使用自己做的這個插件的次數會越來越少,專案已開源,使用說明與原始碼傳送門(https://github.com/Kerinlin/translate-variable)
更多關於VSCode的相關知識,請造訪:vscode教學! !
以上是手把手從0教你開發一個vscode變數翻譯插件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

VisualStudio适合大型项目和需要强大调试功能的开发场景,而VSCode则适合需要灵活性和跨平台开发的场景。VisualStudio提供全面的开发环境,支持.NET开发,集成了调试工具和项目管理功能;VSCode以轻量和扩展性著称,支持多种编程语言,通过插件系统增强功能,适用于现代开发流程。

VisualStudio提供三種版本:Community免費版適用於個人和小型團隊,Professional付費版適合專業開發者和中小型團隊,Enterprise旗艦版面向大型企業和復雜項目。

VisualStudio在.NET开发中价值高,因其功能强大且全面。尽管成本和资源消耗较高,但其带来的效率提升和开发体验改善显著。对于个人开发者和小型团队,Community版是理想选择;大型企业则适合Professional或Enterprise版。

VisualStudio的免費版本包括VisualStudioCommunity和VisualStudioCode。 1.VisualStudioCommunity適用於個人開發者、開源項目和小型團隊,功能強大,適合個人項目和學習編程。 2.VisualStudioCode是一個輕量級的代碼編輯器,支持多種編程語言和擴展,啟動速度快,資源佔用少,適合需要靈活性和可擴展性的開發者。

在Windows8上安裝VisualStudio的步驟如下:1.從微軟官方網站下載VisualStudioCommunity2019安裝包。 2.運行安裝程序並選擇所需組件。 3.完成安裝後即可使用。注意選擇與Windows8兼容的組件,並確保有足夠的磁盤空間和管理員權限。

VSCode可以在大多數現代電腦上運行,只要滿足基本系統要求:1.操作系統:Windows7及以上,macOS10.9及以上,Linux;2.處理器:1.6GHz或更快;3.內存:至少2GBRAM(推薦4GB或更高);4.存儲空間:至少200MB可用空間。通過優化設置和減少擴展使用,可以在低配置電腦上獲得流暢的使用體驗。

要讓程序在Windows8上順暢運行,需採取以下步驟:1.使用兼容性模式,通過代碼檢測並啟用該模式。 2.調整API調用,根據Windows版本選擇適當的API。 3.進行性能優化,盡量避免使用兼容性模式,優化API調用並使用通用控件。

Yes,VSCodeiscompatiblewithWindows8.1)DownloadtheinstallerfromtheVSCodewebsiteandensurethelatest.NETFrameworkisinstalled.2)Installextensionsusingthecommandline,notingsomemayloadslower.3)Manageperformancebyclosingunnecessaryextensions,usinglightweightt


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

Dreamweaver Mac版
視覺化網頁開發工具

禪工作室 13.0.1
強大的PHP整合開發環境

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器