VSCode插件之字数统计、翻译

demonstration-gif


hello world 初体验

环境条件:

  • npm
  • git
  • 最新版的VS Code(我的是1.32.3,结果测试的时候说我版本太低,就升级到了1.33.0)

根据官网给的链接your-first-extension, 我们需要安装一个代码生成工具,减少重复代码的编写。

npm install -g yo generator-code

万事俱备只欠东风,接下来试试官网的hello world,首先是把项目结构搭建出来。

yo code

根据提示,输入自己想做的插件名称,identifier,描述等信息

# ? What type of extension do you want to create? New Extension (TypeScript)
# ? What's the name of your extension? HelloWorld
### Press <Enter> to choose default for all options below ###

# ? What's the identifier of your extension? helloworld
# ? What's the description of your extension? LEAVE BLANK
# ? Enable stricter TypeScript checking in 'tsconfig.json'? Yes
# ? Setup linting using 'tslint'? Yes
# ? Initialize a git repository? Yes
# ? Which package manager to use? npm

然后进入到**./helloworld** 目录,就可以看到目录结构已经出来了。这种级别的 demo 一般都是可以直接跑的。

  • 将**./helloworld**目录放到VS Code中。
  • F5 就会自动进行编译,然后会打开一个Extension Development Host窗口
  • Command+Shift+P 输入Hello World就可以看到效果了。

自带的特效是输出一个“Hello World” 的**InformationMessage**框。具体可以看:
hello-world-demonstration

经过对Hello World的练手,环境搭建,项目目录的搭建基本上就熟悉了,然后就可以着手准备本次的插件开发了。

cd ../ && rm -rf helloworld/

目标功能:实时字数统计 + 翻译选中文本

有些东西不适合从零开始,因为太浪费时间了,不如找点现成的,站在别人的肩膀上迭代。

实时字数统计

所以我打开VS Code 直接在插件市场输入word count,结果出来了一堆,然后找了一个看起来还不赖的,ycjc868-vscode-word-count, 点进去Repository地址,先看看人家是怎么实现的,感觉可用的关键代码有这么几个:

// VSCode 底部状态栏
    private _statusBarItem: vscode.StatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
// 注册光标改变事件
    vscode.window.onDidChangeTextEditorSelection(this.updateWordCount, this, subscriptions);

// 获取当前编辑器对象
    const editor = vscode.window.activeTextEditor;
// 获取文本以及将内容展示到状态栏
    const wordCount = this._getWordCount(doc);
    this._statusBarItem.text = `${wordCount} Words`;
    this._statusBarItem.show();

翻译选中的文本

功能已经完成一半了,接下来是实现第二个功能翻译选中文本,之前写过一个系统级别的翻译的工具,基本原理是:

监听系统剪切板的内容变化,
调用翻译API完成翻译任务,
调用系统GUI组件弹出翻译内容。

能用是能用,就是不太受控制,用的时候开启服务,不用的时候得关掉,要不然疯了一样往外弹提醒。

本次要做一个VS Code中的翻译,这个场景就蛮适合,最起码不会打扰到自己。思路还是看看别人是咋实现类似的功能的。找到了一个**天气预报**的插件,里面有一段代码如下:

const config = vscode.workspace.getConfiguration('remind-me') //获取可配置项中的数据
const appkey = config.hefengAppkey? config.hefengAppkey: 'YOUR_KEY' // 这里放和风天气的KEY
WebRequest.get(`https://way.jd.com/he/freeweather?city=${encodeURI(cityName)}&appkey=${appkey}`).
           then(reps => {
               let rep = JSON.parse(reps.body)
               ...... 
           )

我不会TypeScript,所以使用WebRequest的时候,提示我没有这个类,猜想是需要引入这种脚手架的库,然后搜了一下,找到一个**Web-Request的使用介绍**。

npm install web-request

然后在**extension.ts**中像引入vscode一样引用一下。

import * as vscode from 'vscode';
import * as WebRequest from 'web-request';

有道翻译的API不让免费用了,那就用百度的翻译API(翻译的效果好像也还凑活),锅碗瓢盆都准备好了,现在该淘米了,那就得拿到选中的文本,代码如下:

let selection = editor.selection
let text = editor.document.getText(selection)

经过测试发现,代码是间歇性正常,然后我使用**console.log** 打印了下web请求的结果,发现是返回内容解析出错了,猜想是汉字在URL中有编解码的影响,然后会导致出问题。就拿encodeURI对选中的文本加了下处理。

public _translate(keyword: string): string {
    // 获取选中的文本
    let wcconfig = vscode.workspace.getConfiguration("wordcount");
    let url = wcconfig.transapi ? wcconfig.transapi : "https://fanyi.baidu.com/transapi?from=auto&to=auto&query="
    if(keyword) {
        url = url + encodeURI(keyword)
        WebRequest.get(url).then(resp => {
            let rep = JSON.parse(resp.content);
            console.log(resp.content);
            let transret = rep.data[0].dst;
            this._statusBarItem.text = "[" + keyword + "]:" + transret;
            this._statusBarItem.show();
        });
    }
    return "失败了~~~~(>_<)~~~~"
}

这样就可以正常工作了,但是看到刚才的那个作者的repository中有对于配置文件的使用,为了减少硬编码,咱也试试呗。在**package.json**中加入下面的配置项。

"commands": [
    {
        "command": "extension.wordCount",
        "title": "count Words"
    }
],
"configuration":{
    "type": "object",
    "title": "some configuration for translate",
    "properties": {
        "wordcount.transapi": {
            "type": "string",
            "default": "https://fanyi.baidu.com/transapi?from=auto&to=auto&query=",
            "description": "auto translate api from baidu"
        }
    }
},

拓展代码使用let wcconfig = vscode.workspace.getConfiguration("wordcount");就可以拿到对应的配置值了。

打包、发布

东西做出来,肯定得分享,不然不会有进步的。然后还是看看别人怎么弄的,跟着做就好了。找到了一个VSCode插件开发全攻略(十)打包、发布、升级 真的是详细。

这里我说下我遇到的几个问题。

README.md 文件修改问题
➜  wordcount git:(master) ✗ vsce package
Executing prepublish script 'npm run vscode:prepublish'...

> wordcount@0.0.1 vscode:prepublish /Users/biao/Code/vscode/wordcount
> npm run compile


> wordcount@0.0.1 compile /Users/biao/Code/vscode/wordcount
> tsc -p ./

 ERROR  Make sure to edit the README.md file before you publish your extension.

解决方法:删掉开头自动生成的文本,写点自己的内容就好了。

无法打包
➜  wordcount git:(master) ✗ vsce package
 ERROR  Missing publisher name. Learn more: https://code.visualstudio.com/api/working-with-extensions/publishing-extension#publishing-extensions

解决思路:missing publisher namepackage.json 中加入publisher信息就好了。

仓库缺失问题
➜  wordcount git:(master) ✗ vsce package
Executing prepublish script 'npm run vscode:prepublish'...

> wordcount@0.0.1 vscode:prepublish /Users/biao/Code/vscode/wordcount
> npm run compile


> wordcount@0.0.1 compile /Users/biao/Code/vscode/wordcount
> tsc -p ./

 WARNING  A 'repository' field is missing from the 'package.json' manifest file.
Do you want to continue? [y/N] n

可以看出这里是Warning,所以没有也没关系。如果想上传到GitHub上,开头环境中的git就派上了用场。

git add .
git commit -m 'xxxxxx'
git remote add origin your-git-repository
git push origin master
publish 失败
➜  wordcount git:(master) ✗ vsce puhlish
Usage: vsce [options] [command]

Options:
  -V, --version                        output the version number
  -h, --help                           output usage information

Commands:
  ls [options]                         Lists all the files that will be published
  package [options]                    Packages an extension
  publish [options] [<version>]        Publishes an extension
  unpublish [options] [<extensionid>]  Unpublishes an extension. Example extension id: microsoft.csharp.
  list <publisher>                     Lists all extensions published by the given publisher
  ls-publishers                        List all known publishers
  create-publisher <publisher>         Creates a new publisher
  delete-publisher <publisher>         Deletes a publisher
  login <publisher>                    Add a publisher to the known publishers list
  logout <publisher>                   Remove a publisher from the known publishers list
  show [options] <extensionid>         Show extension metadata
  search [options] <text>              search extension gallery
  *

跟教程上的不一样,怎么就是不成功。后来想了下发布肯定是要身份信息的,照应刚才的Token信息。所以先将publisher登陆下。

➜  wordcount git:(master) ✗ vsce login guoruibiao
Publisher 'guoruibiao' is already known
Do you want to overwrite its PAT? [y/N] y
Personal Access Token for publisher 'guoruibiao': ****************************************************

(node:95091) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
➜  wordcount git:(master) ✗ vsce publish
Executing prepublish script 'npm run vscode:prepublish'...

> wordcount@0.0.1 vscode:prepublish /Users/biao/Code/vscode/wordcount
> npm run compile


> wordcount@0.0.1 compile /Users/biao/Code/vscode/wordcount
> tsc -p ./

This extension consists of 566 separate files. For performance reasons, you should bundle your extension: https://aka.ms/vscode-bundle-extension
Publishing guoruibiao.wordcount@0.0.1...
(node:95103) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
 DONE  Published guoruibiao.wordcount@0.0.1
Your extension will live at https://marketplace.visualstudio.com/items?itemName=guoruibiao.wordcount (might take a few seconds for it to show up).

Token 的生成按照刚才的链接跟着做就好了,publish通过后会返回一个地址:

https://marketplace.visualstudio.com/items?itemName=guoruibiao.wordcount

大概5分钟后就可以访问了。

分发与安装

VS Code 插件市场搜索**word count** 找到作者是guoruibiao的那个,点击**install**,完事。
plugin-market

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐