前端周边 – 手把手教你写VSCode插件

1.前言

喜欢或者尝试过写文章的朋友可能会在需要打符号的时候,中英切换出错,将英文感叹号打成中文感叹号,比如 markdown 语法里展示链接或者图片,如果你打错就会变成下面这样

我是图片啊喂

就很烦,有的朋友就会写完整篇文章之后,统一 ctrl+H 全文替换

我之前就是全文替换那种,写完记得替换还好,要是忘了或者改起以前写过的,那中英文标点穿插出现,那酸爽

作为一个易怒人,我能受得了这气?,一怒之下研读 VSCode 插件 API,直接将中文标点替换成英文标点的功能写成了 VSCode 插件(VSCode 文档写的真好,赞一下),于是就有了这篇文章,手把手教你写一个 VSCode 插件。

2. 准备

众所周知 VSCode 是基于 Electron 框架写的,也就是 javaScript,所以写一个插件对前端仔还是很友好的.

  1. 首先安装环境
$ npm install -g yo generator-code
复制代码
  1. 执行命令
$ yo code
复制代码

yo code

  1. 选择 New Extension (TypeScript)

choose new typescript

  1. 填写项目配置
# ? What type of extension do you want to create? New Extension (TypeScript)
# ? What's the name of your extension? `your-extension-name`
### Press <Enter> to choose default for all options below ###
# ? What's the identifier of your extension? `your-extension-name`
# ? What's the description of your extension? `some description`
# ? Initialize a git repository? Yes
# ? Bundle the source code with webpack? Yes
# ? Which package manager to use? npm
复制代码
$ ? What type of extension do you want to create? New Extension (TypeScript)
$ ? What's the name of your extension? test (你的插件名)
$ ? What's the identifier of your extension? test (你的插件的标识)
$ ? What's the description of your extension? just a test (简单描述)
$ ? Initialize a git repository? no
$ ? Bundle the source code with webpack? Yes
$ ? Which package manager to use? npm
复制代码
  1. 进入项目
$ cd `your-extension-name`
$ code .
复制代码
  1. 可以调试了!

在编辑器中,按 F5,或者点击左边的甲虫进入调试模式,会自动打开一个新的 VSCode 窗口,这个窗口就是给你专门调试插件用的ctrl+shift+P 调出命令面板,输入Hello World,右下角就会弹出Hello World from test的消息,至此,一个输出Hello World,弹出Hello World from test的简单插件就完成了!

hello world

3.项目目录

看到目录的那一刻,你会感觉非常亲切,因为这就是个 node 项目目录,^3^

项目目录

  1. 编写的核心文件

package.jsonextension.ts

  1. Hello World 插件工作流程及基本概念

    既然是 webpack 打包的,那从哪里看起就再简单不过了,打开webpack.config.js,看到entry'./src/extension.ts',那就是项目入口

import * as vscode from "vscode";
export function activate(context: vscode.ExtensionContext) {
 console.log('Congratulations, your extension "test" is now active!');
 let disposable = vscode.commands.registerCommand("test.helloWorld", () => {
   vscode.window.showInformationMessage("Hello World from test!");
 });
 context.subscriptions.push(disposable);
}
export function deactivate() {}
复制代码

该入口导出两个函数activatedeactivate英语好的应该看懂,也应该猜的出来,这第一个函数是插件启用的时候调用的,第二个函数是插件关闭的时候调用的。

其中activate函数中调用两个内置 API,注册了nametest.helloworld的命令,该命令的作用就是传入回调中写的输出刚才看到的信息

核心逻辑写在这了,搞懂了,那么问题来了,什么时候插件会启用?

这就要说到第二个核心文件package.json


package.json中包含了一些通用属性,比如nameversion,但还有一些是 vscode 专属的配置属性,比如说contributesactivationEvents,眼尖的同学可能已经注意到activationEvents中就有提到启用的时机

"activationEvents": [
    "onCommand:test.helloWorld"
],
"contributes": {
    "commands": [
        {
            "command": "test.helloWorld",
            "title": "Hello World"
        }
    ]
},
复制代码

其中activationEvents说明如下,表示插件激活的条件

activationEvents

contributescommands配置项就是配置命令面板输入字符串和响应得命令得映射

HelloWorld 流程总结

  1. contributescommands配置项配置命令面板输入字符串和应该响应命令
  2. extension.tsactivate中注册命令和命令具体逻辑
  3. activationEvents配置插件启用时机

4. 实现目标

到这里,我们回顾初心,我们是要写一个将 markdown 文件中的中文字符替换成英文字符的插件,那怎么着手呢?这时候就要泡上一杯咖啡,轻轻的打开官网文档

one year later

从官网可以了解到,一个插件可以拓展一下几个方面

  1. Common Capabilities
  2. Theming
  3. Declarative Language Features
  4. Programmatic Language Features
  5. Workbench Extensions
  6. Debugging

这里就不深入说明了,需要详解的请移步 Extensions Capabilities Overview

回到需求,目标是用户调出命令面板或者使用快捷键就可以马上将中文标点转换为英文标点,主要分为一下几个步骤:

  1. 首先定义在package.json中定义命令和对应快捷键
"contributes": {
    "commands": {
        "command": "test.replace",
        "title": "markdown cp replacer"
    },
    "keybindings": {
        "command": "test.replace",
        "key": "alt+f"
    }
},
复制代码
  1. 设置插件启用时机,显然这里是当文件以.md 结尾时启用
"activationEvents": [
    "onLanguage:markdown"
],
复制代码
  1. 编写具体转换逻辑
  • 注册自定义命令
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
  vscode.commands.registerCommand("test.replace", () => {
    replace();
  })
);
}
复制代码
  • 完善转换逻辑函数
const fs = require("fs");
//中文字符
const CP = [",", ":", "?", "!", "。", "“", "”", "(", ")"];
//用于替换的英文字符
const EP = [",", ":", "?", "!", ".", '"', '"', "(", ")"];
const map = new Map();
let len = CP.length;
for (let i = 0; i < len; i++) {
map.set(CP[i], EP[i]);
}
function replace() {
let fileName: string | undefined =
  vscode.window.activeTextEditor?.document.fileName;
let content: string;
try {
  content = fs.readFileSync(fileName).toString();
} catch (err) {
  throw err;
}
let charArr = content.split("");
for (let i = 0; i < charArr.length; i++) {
  let char = charArr[i];
  if (map.has(char)) {
    charArr[i] = map.get(char);
  }
}
content = charArr.join("");
fs.writeFile(fileName, content, (err: Error) => {
  if (err) {
    throw err;
  }
});
}
复制代码
  1. 完成!

运行debug,输入快捷键alt+f就可以马上替换了.

5.发布与迭代

官方指引

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享