「VS Code 整活」100行代码,写一个超实用的悬浮翻译插件

Posted 笑妄²º²¹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「VS Code 整活」100行代码,写一个超实用的悬浮翻译插件相关的知识,希望对你有一定的参考价值。

前言

要说哪个插件对效率提升最大,可能各有推荐,各有千秋。但我要说对初学者,以及英文有亿点点差的同学来讲:翻译,是日常开发中必不可少的一环。在下找过N个​​VSCode​​ 翻译插件 发现一个神器:

「VS

​VSCode 插件:Google Translate Extension​

这款插件不像其它要么需科学上网,要么强绑定快捷键的憨憨插件,有个最直观的功能:​选中悬浮翻译「VS

啊这...也太作弊了吧,编程能力+10086。

「VS

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

「VS

撒话不说,开干!

1. 代码目录分析

「VS

其中代码逻辑都在​​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​​行。

2. 源码分析

精简完的入口文件:

// 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;

2.1 初始化配置

// 获取用户状态,防止重复使用
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);

2.2 编写触发函数

// 向文件类型提供悬停内容的简单方法
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);




)

其中几个关键点:

  1. ​vscode.languages.registerHoverProvider(scheme: file,...​​: 向文件类型提供悬停内容的简单方法。
  2. 中间的两端​​if​​: 检验 从后往前 或 从前往后 选择的内容是否满足需求。

然后到了悬停调用

await translate(editor.document.getText(selection), langTo);

2.3 触发翻译

再来看​​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;
  1. ​@imlinhanchao/google-translate-api​​:是作者集成的翻译API。
  2. ​getConfig​​​:获取当前​​vscode​​的首选和次选语言,若无则自动翻译(默认英语-> 汉语)。

整个文件导出一个翻译方法。

中间那段正则,可以解析出驼峰函数

word = word.replace(/([a-z])([A-Z])/g, "$1 $2")
.replace(/([_])/g, " ").replace(/=/g, = )
.replace(/(\\b)\\.(\\b)/g, $1 \\n>\\n $2 );

「VS

2.4 显示悬停

回到​​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));

拿到翻译结果后,触发显示为:

「VS

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

「VS

这个插件作为一个​​vscode​​插件开发初体验,是不错的。

2.5 额外小发现:​​google-translate-api​

​一个用于 Google 翻译的免费且无限制的 API

以上是关于「VS Code 整活」100行代码,写一个超实用的悬浮翻译插件的主要内容,如果未能解决你的问题,请参考以下文章

10 个你可能还不知道 VS Code 使用技巧(超实用!)

零基础 | 如何用VS Code写C/C++程序 - 安装与配置

实用VS Code 插件汇总

Mac 系统下VS Code写python时,怎么设置代码提示和补全

VS Code 折腾记 - (19) 一些相对实用的编码体验插件(偏前端)

CODE[VS]1160 蛇形矩阵