从 0 开始编写一个非常好用的 VSCode 翻译插件。
项目简介
线上地址
https://github.com/ringcrl/vscode-translator
功能演示
- 长句子翻译
- 高度不可定制化生词本功能
show time…
环境搭建
全局依赖
1
npm install -g yo generator-code vsce
生成代码
1
yo code
- 开发什么东西(TS)
- 扩展的名称
- 各种配置项…
项目结构
开发模块
package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{
"name": "vscode-translator", // 插件扩展名称(对应创建项目时候的输入)
"displayName": "vscode-translator",
"description": "vscode translator", // 插件扩展的描述(对应创建项目时候的输入)
"version": "0.0.1",
"publisher": "Chenng", // 发布时候的一个名称(对应创建项目时候的输入)
"engines": {
"vscode": "^0.10.10"
},
"categories": ["Other"],
"activationEvents": [
"onCommand:extension.vscodeTranslate" // 这种是通过输入命令来触发执行的
],
"main": "./out/src/extension", // 这个是配置 TypeScript 编译成 js 的输出目录
"contributes": {
"commands": [
{
// title 和 command 是一个对应关系的
"command": "extension.vscodeTranslate", // 这个是对应上面那个命令触发的,在代码里面也要用到
"title": "VSCode Translate" // 这个是我们在 vscode 里面输入的命令
}
],
"keybindings": [
{
// 快捷键绑定
"command": "extension.vscodeTranslate",
"key": "meta+t",
"mac": "cmd+shift+t",
"when": "editorTextFocus"
}
]
},
"scripts": {
// 是在发布打包,或者其他运行时候,要执行的一些脚本命令
"vscode:prepublish": "node ./node_modules/vscode/bin/compile",
"compile": "node ./node_modules/vscode/bin/compile -watch -p ./",
"postinstall": "node ./node_modules/vscode/bin/install"
},
"devDependencies": {
// 这是开发的依赖包,如果有其他的依赖包,并要打包的话,需要把dev去掉
"typescript": "^1.8.5",
"vscode": "^0.11.0"
}
}
extension.ts
注册事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
function activate(context: ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log(
'Congratulations, your extension "vscode-translator" is now active!'
);
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
const disposable = commands.registerCommand(
"extension.vscodeTranslate",
async () => {
// The code you place here will be executed every time your command is executed
const editor = window.activeTextEditor;
if (!editor) {
return console.log("no open text editor!");
}
const selection = editor.selection;
let srcText = editor.document.getText(selection);
if (!srcText) {
return;
}
const sougouFetchResult: any = await translator.sougouTranslate(srcText);
if (sougouFetchResult.errorCode !== 0) {
return;
}
const translateText = sougouFetchResult.translate.dit;
showTranslateResult(srcText, translateText);
}
);
context.subscriptions.push(disposable);
}
实现逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
async function showTranslateResult(srcText: string, translateText: string) {
const selectedText = await window.showInformationMessage(
`${srcText}\n${translateText}`,
{ modal: true },
"加入生词库"
);
if (selectedText === "加入生词库") {
const timer = setInterval(async () => {
const selectedText = await window.showInformationMessage(
srcText,
{ modal: false },
"我已记住",
"查看翻译"
);
if (selectedText === "我已记住") {
clearTimeout(timer);
} else if (selectedText === "查看翻译") {
const sougouFetchResult: any = await translator.sougouTranslate(
srcText
);
if (sougouFetchResult.errorCode !== 0) {
return;
}
const translateText = såougouFetchResult.translate.dit;
await window.showInformationMessage(translateText, { modal: false });
}
}, REVIEW_INTERVAL);
}
}
打包与发布
1
npm install -g vsce
打包
1
vsce package
直接安装打包出来的 xxx-0.0.1.vsix 文件即可。
发布
1
2
3
4
5
# 第一次发布时需要,输入 【Personal access tokens】
# 获取token:https://ringcrl.visualstudio.com/_usersSettings/tokens
vsce login chenng
vsce publish