Develop vscode plugin variable translation from zero to one
The reason for the demand is that English slag often encounters a variable in the development process that knows what Chinese is called, but the English word may be forgotten or unknown. At this time, I used to open the browser, open Google Translate, and enter Chinese. , copy the English, then switch back to vscode, paste the result. It's really troublesome. When I was young, my memory was good. I could remember most of the English words. The number of times is also increasing, so I developed this plug-in after thinking about it. Because I am also the plug-in development that I have learned from scratch in the past few days, this article completely records the plug-in development road developed by Xiaobai. The content is mainly an introduction to actual combat, mainly from four aspects to fully display the entire plug-in. The complete journey from functional design to release.
- feature design
- Environment construction
- Plug-in function development
- Plug-in package release
The plugin has been launched, the vscode plugin store can search for Translate Variable to experience it, and the code is also open source, the source code here
feature design
The function is mainly two functions, Chinese to English, other languages to Chinese
- Replace Chinese variables with translated English variables. Multiple words need to be automatically humped. The solution is the "English stuck" that is often encountered in daily development.
- Word translation, automatically translates various languages into Chinese. This solves the scenario that sometimes when you look at the comments of the source code of foreign projects, you may encounter words that you cannot understand and do not know what they mean, which affects the efficiency.
Environment construction
The first step to get started, the environment is built
Install scaffolding, yo and generator-code , these two tools can help us build projects quickly, see Github
//安装 yarn global add yo generator-code
Install vsce, vsce can be used to package the developed code into a file with a .vsix suffix, which is convenient for uploading to the Microsoft plug-in store or local installation
yarn global add vsce
Generate and initialize the project, fill in the initialization information according to your own situation
//初始化生成项目 yo code
After this step, choose to open directly, Open with code
will automatically create a workspace after opening, and generate these files. You can delete the files according to your own needs. After this step, we can directly develop and debug
How does
Go to run and debug panel and click Run Extention , or shortcut key F5 , you can directly click the debug button on the touch bar on mac
After opening, a new vscode window will pop up, this new window is your test environment ( extension development host ), the plug-in function you do is to test in this new window, and the printed message is debugged In the console , such as the built-in example, in our new window cmd/ctrl+shift+p and input Hello world , some information will be printed on the console of the previous window
At this point, the development preparation environment is ready, and the next step is to start the official plug-in function development
Plug-in function development
In the plugin development, there are two important files, one is package.json , the other is extention.js
Important Document Description
package.json
- activationEvents used to register activation events to indicate under what circumstances the active function in extension.js will be activated. Common ones are onLanguage , onCommand ... For more information, see vscode documentation activationEvents
- main represents the main entry of the plugin
- Contributes to registration command (Commands) , binding shortcuts (the KeyBindings) , configuration settings (the Configuration) and so on, more configurable items to see document
extention.js
The main function of extention.js is to serve as the implementation point of the plug-in function. The development of the plug-in function is completed through the active and deactive functions, as well as the api provided by vscode and some event hooks.
Implement translation function
The translation here mainly uses 3 services, Google, Baidu translation, Youdao translation.
Google Translate uses @vitalets/google-translate-api , no configuration is required, but you need to be able to access the external network environment
const translate = require('@vitalets/google-translate-api'); async function getGoogleTransResult(text, opt) { const { from, to } = opt; try { const result = await translate(text, { from: from, to: to }); console.log("[ 谷歌翻译 ]", result); return result.text; } catch (error) { console.log(error); } } module.exports = getGoogleTransResult
Baidu translation, Baidu translation is relatively simple, apply for a service, get the appid and key, and then construct the request url to directly request it. If you don’t know how to apply, you can check my previous article Electron+Vue creates a local file from scratch Translator to apply
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;
Youdao translation needs to apply for an app id and an app key. Newcomers register to provide 50 free coupons, but they will be charged after they are used up, which is not very cost-effective.
const config = require('../config/index.js'); const { createHash } = require('crypto'); const qs = require('querystring'); const axios = require("axios"); function hash(string) { return createHash('sha256').update(string).digest('hex'); } function getInput(text) { if (!text) { return; } let input; const strLength = text.length; if (strLength <= 20) { input = text; } else { input = `${text.substring(0, 10)}${strLength}${text.substring(strLength - 10, strLength)}`; } return input; } async function getYouDaoTransResult(text, opt = {}) { const { from, to, appid, secretKey } = opt; const input = getInput(text); const salt = (new Date).getTime(); const curtime = Math.round(new Date().getTime() / 1000); const str = `${appid}${input}${salt}${curtime}${secretKey}`; const sign = hash(str); const params = { q: text, appKey: appid, salt: salt, from: from, to: to, sign: sign, signType: "v3", curtime: curtime, } try { const res = await axios.post(config.youdaoBaseUrl, qs.stringify(params)); console.log(`有道翻译结果 ${res.data.translation[0]}`); return res.data.translation[0]; } catch (err) { console.log(error); } } module.exports = getYouDaoTransResult
get selected text
Use the event hook onDidChangeTextEditorSelection to get the selected text
onDidChangeTextEditorSelection(({ textEditor, selections }) => {
text = textEditor.document.getText(selections[0]);
})
Get updates for configuration items
Obtain the configuration items of the workspace through vscode.workspace.getConfiguration , and then monitor the changes onDidChangeConfiguration
Get the update configuration item
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);
Monitor configuration item changes
const { getConfiguration, onDidChangeConfiguration } = vscode.workspace;
const config = getConfiguration();
//监听变动
const disposeConfig = onDidChangeConfiguration(() => {
config = getConfiguration();
})
Monitor the changes of individual configuration items
const disposeConfig = onDidChangeConfiguration((e) => {
if (e && e.affectsConfiguration(BAIDU_KEY)) {
//干些什么
}
})
Get the currently open editor object
vscode.window.activeTextEditor represents the currently open editor. If you switch tabs without setting monitoring, this object will not be updated automatically, so you need to use onDidChangeActiveTextEditor to monitor and replace the previous editor object
const { activeTextEditor, onDidChangeActiveTextEditor } = vscode.window;
let active = activeTextEditor;
const edit = onDidChangeActiveTextEditor((textEditor) => {
console.log('activeEditor改变了');
//更换打开的编辑器对象
if (textEditor) {
active = textEditor;
}
})
Word-marking translation hover prompt
By vscode.languages.registerHoverProvider registered a Hover, then activeTextEditor translation to get the selected words, and then by new new vscode.Hover will prompt translation results suspension
// 划词翻译检测
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}`);
}
})
replace selected text
Get to activeTextEditor , calling his Edit method, and then use the callback the replace
//是否替换原文
if (isReplace) {
let selectedItem = active.selection;
active.edit(editBuilder => {
editBuilder.replace(selectedItem, result)
})
}
copy to clipboard
use vscode.env.clipboard.writeText;
// 是否复制翻译结果
if (isCopy) {
vscode.env.clipboard.writeText(result);
}
Camel handling
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;
Shortcut key bindings
Register the keybindings set in package.json before binding through vscode.commands.registerCommand . It should be noted that the first parameter of registerCommand needs to be consistent with the command of keybindings before binding.
registerCommand('translateVariable.toEN', async() => {
//do something
})
//package.json
"keybindings": [{
"key": "ctrl+t",
"mac": "cmd+t",
"when": "editorTextFocus",
"command": "translateVariable.toEN"
}],
Plug-in package release
Bale
vsce package
After packaging, a plugin with a .vsix suffix will be generated in the directory
release
Plug-in release is mainly to transfer the packaged vsix suffix plug-in to the Microsoft vscode plug-in store, and of course it can also be installed and used locally.
incoming store
To publish online, you need to to the 161dda72b2e978 Microsoft Plugin Store management page to create the publisher information. If you do not have a Microsoft account, you need to apply for it.
Once created, choose to publish to vscode store
install
You can directly install the .vsix suffix plugin locally, find the plugin menu
Select installation from the VSIX , install packaged plug-ins like the above
At last
The Chinese information of vscode is a bit small. This time I spent most of my time reading English documents and looking for information on the Internet. English is really important. I will learn more English later. I hope I will use this plugin I made myself. The number of times will be less and less, the project has been open source, instructions and source code portal
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。