文章目录
- 要说哪个插件对效率提升最大,可能各有推荐,各有千秋。但我要说对初学者,以及英文有亿点点差的同学来讲:翻译,是日常开发中必不可少的一环。在下找过N个VSCode 翻译插件 发现一个神器: VSCode 插件:Google Translate Extension 这款插件不像其它要么需科学上网,要么强绑定快捷键的憨憨插件,有个最直观的功能:选中悬浮翻译 啊这...也太作弊了吧,编程能力+10086。 因为这两年都在从事VSCode二次/插件 开发,这个功能深得我心,于是想捣腾一下,看看能不能写轮眼学习一番 撒话不说,开干!
- 其中代码逻辑都在src目录里。 command.js //全部命令extension.js //插件入口文件tranlate.js //翻译工具函数 先从入口文件extension.js出发: // The module 'vscode' contains the VS Code extensibility API// Import the module and reference it with the alias vscode in your code belowconst command = require('./command')function activate(context) { console.log('Congratulations, your extension "vsc-google-translate" is now active!'); command.initSetting(context); context.subscriptions.push(command.hoverDisposable); context.subscriptions.push(command.tranDisposable); context.subscriptions.push(command.switchDisposable); context.subscriptions.push(command.copyDisposable); context.subscriptions.push(command.replaceDisposable); context.subscriptions.push(command.canDisposable); context.subscriptions.push(command.switchLangDisposable); context.subscriptions.push(command.fromLangDisposable); context.subscriptions.push(command.settingsDisposable);}exports.activate = activate;function deactivate() {}exports.deactivate = deactivate; 可以看到相当整洁,其中我们关注的功能只有hoverDisposable和tranDisposable,为了方便阅读,我精简了一遍。从500行减到100行。
- 精简完的入口文件:
// The module 'vscode' contains the VS Code extensibility API// Import the module and reference it with the alias vscode in your code belowconst command = require('./command')function activate(context) { console.log('Congratulations, your extension "vsc-google-translate" is now active!'); command.initSetting(context); context.subscriptions.push(command.hoverDisposable);}exports.activate = activate;function deactivate() {}exports.deactivate = deactivate;
- // 获取用户状态,防止重复使用function initSetting(cxt) { hoverOpen = cxt.globalState.get('hover') || false; langFrom = cxt.globalState.get('fromLang') || 'auto' if (!translate.languages.isSupported(langFrom)) langFrom = 'auto'; cxt.globalState.update('hover', hoverOpen);}
- // 向文件类型提供悬停内容的简单方法let hoverDisposable = vscode.languages.registerHoverProvider({scheme: 'file'}, { provideHover: async (document, position, token) => { // 获取正在激活的编辑器窗口区域 let editor = vscode.window.activeTextEditor; if (!editor || !hoverOpen) { return; // No open text editor } let length = editor.selections.length; for (let i = 0; i < length; i++) { let selection = editor.selections[i]; let line = { begin: Math.min(selection.anchor.line, selection.active.line), end: Math.max(selection.anchor.line, selection.active.line) }, character = { begin: Math.min(selection.anchor.character, selection.active.character), end: Math.max(selection.anchor.character, selection.active.character) }; // 这里是检验 从后往前 或 从前往后 选择的内容。 if (line.begin > position.line || character.begin > position.character) continue; if (line.end < position.line || character.end < position.character) continue; try { // 开始翻译 let trans = await translate(editor.document.getText(selection), langTo); if (!trans) return; let word = trans.word // 悬停显示的内容 let pre = `<strong>[Google Translate](https://translate.google.cn/?sl=auto&tl=${trans.lang.to}&text=${encodeURI(trans.text)})</strong>\n\n`; console.log("word", word); return new vscode.Hover(pre + word.replace(/\r\n/g, ' \r\n')); } catch (error) { return new vscode.Hover('<strong>[Error](https://github.com/imlinhanchao/vsc-google-translate/issues)</strong>\n\n' + error.message); } } }}) 其中几个关键点: vscode.languages.registerHoverProvider({scheme: 'file'},{...}: 向文件类型提供悬停内容的简单方法。 中间的两端if: 检验 从后往前 或 从前往后 选择的内容是否满足需求。 然后到了悬停调用 await translate(editor.document.getText(selection), langTo);
- 再来看tranlate.js,我稍微精简了下: const vscode = require('vscode');const translator = require('@imlinhanchao/google-translate-api');let config = {};async function translate(text, lang) { try{ let result = await translator(text, { from: lang.from == 'auto' ? undefined : lang.from, to: lang.to, }) return { lang, text, word: result.text || '', candidate: result.candidates }; } catch (err) { throw new Error(`Translate failed, Error message: '${err.message}'. Please post an issues for me.`); } }function getConfig() { let keys = [ 'google-translate.firstLanguage', 'google-translate.secondLanguage', ]; let values = {}; keys.forEach(k => values[k] = vscode.workspace.getConfiguration().get(k)) return values;}module.exports = async (word, l, from='auto') => { if (word == '') return null; config = getConfig(); let lang = { from, to: l || config['google-translate.firstLanguage'] }; // 解析驼峰函数。 word = word.replace(/([a-z])([A-Z])/g, "$1 $2") .replace(/([_])/g, " ").replace(/=/g, ' = ') .replace(/(\b)\.(\b)/g, '$1 \n{>}\n $2 '); let tran = await translate(word, lang); // 若翻译无结果,则调用翻译成第二语言 if (tran.word.replace(/\s/g, '') == word.replace(/\s/g, '') || !tran.word.trim()) { lang.to = config['google-translate.secondLanguage']; let tranSecond = await translate(word, lang); if (tranSecond.word) tran = tranSecond; } // 去除多余字符 tran.word = tran.word.replace(/\n{>}\n/g, '.'); tran.candidate = tran.candidate.map(c => c.replace(/{([^>]*?)>}/g, '$1\n{>}').replace(/\n{>}\n/g, '.')); return tran;};module.exports.getConfig = getConfig;module.exports.languages = translator.languages; @imlinhanchao/google-translate-api:是作者集成的翻译API。 getConfig:获取当前vscode的首选和次选语言,若无则自动翻译(默认英语-> 汉语)。 整个文件导出一个翻译方法。 中间那段正则,可以解析出驼峰函数 word = word.replace(/([a-z])([A-Z])/g, "$1 $2") .replace(/([_])/g, " ").replace(/=/g, ' = ') .replace(/(\b)\.(\b)/g, '$1 \n{>}\n $2 ');
- 回到hoverDisposable: let trans = await translate(editor.document.getText(selection), langTo);if (!trans) return;let word = trans.word let pre = `<strong>[Google Translate](https://translate.google.cn/?sl=auto&tl=${trans.lang.to}&text=${encodeURI(trans.text)})</strong>\n\n`;return new vscode.Hover(pre + word.replace(/\r\n/g, ' \r\n')); 拿到翻译结果后,触发显示为: 这里一个很有意思的点,给你拼装了一段可打开的Google Translate链接,非常体贴了可以说。 这个插件作为一个vscode插件开发初体验,是不错的。
- 一个用于 Google 翻译的免费且无限制的 API
- 约有一年没写文章了,这段时间都在摸鱼以及健身。都在写vscode二次/插件开发。比较少关注新技术。准备重新出发,整整账号了。
- VSCode 插件:Google Translate Extension 精简后的:https://github.com/roger-hiro/vscode-google-translate 不想拉代码的同学可以试试CS的自定义模板 来自:https://cloudstudio.net/templates/5oulv1ZVoy,点击图标
要说哪个插件对效率提升最大,可能各有推荐,各有千秋。但我要说对初学者,以及英文有亿点点差的同学来讲:翻译,是日常开发中必不可少的一环。在下找过N个VSCode 翻译插件 发现一个神器:

这款插件不像其它要么需科学上网,要么强绑定快捷键的憨憨插件,有个最直观的功能:选中悬浮翻译
啊这...也太作弊了吧,编程能力+10086。

因为这两年都在从事VSCode二次/插件 开发,这个功能深得我心,于是想捣腾一下,看看能不能写轮眼学习一番

撒话不说,开干!

其中代码逻辑都在src目录里。
command.js //全部命令
extension.js //插件入口文件
tranlate.js //翻译工具函数
先从入口文件extension.js出发:
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const command = require('./command')
function activate(context) {
console.log('Congratulations, your extension "vsc-google-translate" is now active!');
command.initSetting(context);
context.subscriptions.push(command.hoverDisposable);
context.subscriptions.push(command.tranDisposable);
context.subscriptions.push(command.switchDisposable);
context.subscriptions.push(command.copyDisposable);
context.subscriptions.push(command.replaceDisposable);
context.subscriptions.push(command.canDisposable);
context.subscriptions.push(command.switchLangDisposable);
context.subscriptions.push(command.fromLangDisposable);
context.subscriptions.push(command.settingsDisposable);
}
exports.activate = activate;
function deactivate() {
}
exports.deactivate = deactivate;
可以看到相当整洁,其中我们关注的功能只有hoverDisposable和tranDisposable,为了方便阅读,我精简了一遍。从500行减到100行。
精简完的入口文件:
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const command = require('./command')
function activate(context) {
console.log('Congratulations, your extension "vsc-google-translate" is now active!');
command.initSetting(context);
context.subscriptions.push(command.hoverDisposable);
}
exports.activate = activate;
function deactivate() {
}
exports.deactivate = deactivate;
// 获取用户状态,防止重复使用
function initSetting(cxt) {
hoverOpen = cxt.globalState.get('hover') || false;
langFrom = cxt.globalState.get('fromLang') || 'auto'
if (!translate.languages.isSupported(langFrom)) langFrom = 'auto';
cxt.globalState.update('hover', hoverOpen);
}
function initSetting(cxt) {
hoverOpen = cxt.globalState.get('hover') || false;
langFrom = cxt.globalState.get('fromLang') || 'auto'
if (!translate.languages.isSupported(langFrom)) langFrom = 'auto';
cxt.globalState.update('hover', hoverOpen);
}
// 向文件类型提供悬停内容的简单方法
let hoverDisposable = vscode.languages.registerHoverProvider({scheme: 'file'}, {
provideHover: async (document, position, token) => {
// 获取正在激活的编辑器窗口区域
let editor = vscode.window.activeTextEditor;
if (!editor || !hoverOpen) {
return; // No open text editor
}
let length = editor.selections.length;
for (let i = 0; i < length; i++) {
let selection = editor.selections[i];
let line = {
begin: Math.min(selection.anchor.line, selection.active.line),
end: Math.max(selection.anchor.line, selection.active.line)
}, character = {
begin: Math.min(selection.anchor.character, selection.active.character),
end: Math.max(selection.anchor.character, selection.active.character)
};
// 这里是检验 从后往前 或 从前往后 选择的内容。
if (line.begin > position.line || character.begin > position.character) continue;
if (line.end < position.line || character.end < position.character) continue;
try {
// 开始翻译
let trans = await translate(editor.document.getText(selection), langTo);
if (!trans) return;
let word = trans.word
// 悬停显示的内容
let pre = `<strong>[Google Translate](https://translate.google.cn/?sl=auto&tl=${trans.lang.to}&text=${encodeURI(trans.text)})</strong>\n\n`;
console.log("word", word);
return new vscode.Hover(pre + word.replace(/\r\n/g, ' \r\n'));
} catch (error) {
return new vscode.Hover('<strong>[Error](https://github.com/imlinhanchao/vsc-google-translate/issues)</strong>\n\n' + error.message);
}
}
}
})
let hoverDisposable = vscode.languages.registerHoverProvider({scheme: 'file'}, {
provideHover: async (document, position, token) => {
// 获取正在激活的编辑器窗口区域
let editor = vscode.window.activeTextEditor;
if (!editor || !hoverOpen) {
return; // No open text editor
}
let length = editor.selections.length;
for (let i = 0; i < length; i++) {
let selection = editor.selections[i];
let line = {
begin: Math.min(selection.anchor.line, selection.active.line),
end: Math.max(selection.anchor.line, selection.active.line)
}, character = {
begin: Math.min(selection.anchor.character, selection.active.character),
end: Math.max(selection.anchor.character, selection.active.character)
};
// 这里是检验 从后往前 或 从前往后 选择的内容。
if (line.begin > position.line || character.begin > position.character) continue;
if (line.end < position.line || character.end < position.character) continue;
try {
// 开始翻译
let trans = await translate(editor.document.getText(selection), langTo);
if (!trans) return;
let word = trans.word
// 悬停显示的内容
let pre = `<strong>[Google Translate](https://translate.google.cn/?sl=auto&tl=${trans.lang.to}&text=${encodeURI(trans.text)})</strong>\n\n`;
console.log("word", word);
return new vscode.Hover(pre + word.replace(/\r\n/g, ' \r\n'));
} catch (error) {
return new vscode.Hover('<strong>[Error](https://github.com/imlinhanchao/vsc-google-translate/issues)</strong>\n\n' + error.message);
}
}
}
})
其中几个关键点:
-
vscode.languages.registerHoverProvider({scheme: 'file'},{...}: 向文件类型提供悬停内容的简单方法。 - 中间的两端
if: 检验 从后往前 或 从前往后 选择的内容是否满足需求。
然后到了悬停调用
await translate(editor.document.getText(selection), langTo);
再来看tranlate.js,我稍微精简了下:
const vscode = require('vscode');
const translator = require('@imlinhanchao/google-translate-api');
let config = {};
async function translate(text, lang) {
try{
let result = await translator(text, {
from: lang.from == 'auto' ? undefined : lang.from,
to: lang.to,
})
return {
lang,
text,
word: result.text || '',
candidate: result.candidates
};
} catch (err) {
throw new Error(`Translate failed, Error message: '${err.message}'. Please post an issues for me.`);
}
}
function getConfig() {
let keys = [
'google-translate.firstLanguage',
'google-translate.secondLanguage',
];
let values = {};
keys.forEach(k => values[k] = vscode.workspace.getConfiguration().get(k))
return values;
}
module.exports = async (word, l, from='auto') => {
if (word == '') return null;
config = getConfig();
let lang = {
from,
to: l || config['google-translate.firstLanguage']
};
// 解析驼峰函数。
word = word.replace(/([a-z])([A-Z])/g, "$1 $2")
.replace(/([_])/g, " ").replace(/=/g, ' = ')
.replace(/(\b)\.(\b)/g, '$1 \n{>}\n $2 ');
let tran = await translate(word, lang);
// 若翻译无结果,则调用翻译成第二语言
if (tran.word.replace(/\s/g, '') == word.replace(/\s/g, '') || !tran.word.trim()) {
lang.to = config['google-translate.secondLanguage'];
let tranSecond = await translate(word, lang);
if (tranSecond.word) tran = tranSecond;
}
// 去除多余字符
tran.word = tran.word.replace(/\n{>}\n/g, '.');
tran.candidate = tran.candidate.map(c => c.replace(/{([^>]*?)>}/g, '$1\n{>}').replace(/\n{>}\n/g, '.'));
return tran;
};
module.exports.getConfig = getConfig;
module.exports.languages = translator.languages;
-
@imlinhanchao/google-translate-api:是作者集成的翻译API。 -
getConfig:获取当前vscode的首选和次选语言,若无则自动翻译(默认英语-> 汉语)。
整个文件导出一个翻译方法。
中间那段正则,可以解析出驼峰函数
word = word.replace(/([a-z])([A-Z])/g, "$1 $2")
.replace(/([_])/g, " ").replace(/=/g, ' = ')
.replace(/(\b)\.(\b)/g, '$1 \n{>}\n $2 ');

回到hoverDisposable:
let trans = await translate(editor.document.getText(selection), langTo);
if (!trans) return;
let word = trans.word
let pre = `<strong>[Google Translate](https://translate.google.cn/?sl=auto&tl=${trans.lang.to}&text=${encodeURI(trans.text)})</strong>\n\n`;
return new vscode.Hover(pre + word.replace(/\r\n/g, ' \r\n'));
拿到翻译结果后,触发显示为:

这里一个很有意思的点,给你拼装了一段可打开的Google Translate链接,非常体贴了可以说。

这个插件作为一个vscode插件开发初体验,是不错的。
一个用于 Google 翻译的免费且无限制的 API

约有一年没写文章了,这段时间都在摸鱼以及健身。都在写vscode二次/插件开发。比较少关注新技术。准备重新出发,整整账号了。
精简后的:https://github.com/roger-hiro/vscode-google-translate

不想拉代码的同学可以试试CS的自定义模板
来自:https://cloudstudio.net/templates/5oulv1ZVoy,点击图标
