本篇文章带大家从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提供三种版本: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调用并使用通用控件。

是的,vscodeiscompatiblewithwindows8.1)下载theinstallerfromtherfromthevscodewebsiteandensuretheletheLatest.netframeworksinstalled.2)installextensionsionsthecommandline,installextensions inthecommandline,notsomemememandline,NoteMemeMemAlandlower.3)noteSmomeMayMayload

VSCode是轻量级代码编辑器,适用于多种语言和扩展;VisualStudio是功能强大的IDE,主要用于.NET开发。1.VSCode基于Electron,支持跨平台,使用Monaco编辑器。2.VisualStudio使用微软自主技术栈,集成调试和编译器。3.VSCode适合简单任务,VisualStudio适合大型项目。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

SublimeText3 Linux新版
SublimeText3 Linux最新版

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

记事本++7.3.1
好用且免费的代码编辑器

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。