Skip to content
Published at:

VSCode插件开发

VSCode Overview

Hello world

开发第一个VSCode插件

  1. 安装环境
  2. 创建项目
  3. 项目结构
  4. 编译、运行、调试
  5. 打包、安装

1. 安装环境

bash
# 1. Install Nodejs 正常安装流程既可

# 2. install Yeoman and VS Code Extension Generator (全局安装)
#    用来生成项目模板代码
$ npm install -g yo generator-code

# 3. 用来打包发布插件
$ npm install -g @vscode/vsce

2. 创建项目

bash
$ yo code

     _-----_     ╭──────────────────────────╮
    |       |   Welcome to the Visual
    |--(o)--|   Studio Code Extension
   `---------´   │        generator!        │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? Hello world
? What's the identifier of your extension? HelloWorldID
? What's the description of your extension?
? Initialize a git repository? Yes
? Bundle the source code with webpack? No
? Which package manager to use? npm

# 下载项目的依赖
$ cd ${project_dir}
$ npm install

3. 项目结构

bash
$ tree .
├── .vscode
   ├── launch.json     // 调试配置
   └── tasks.json      // task任务配置
├── src
   └── extension.ts    // 程序代码
├── package.json        // 项目配置
├── tsconfig.json       // TypeScript配置
  • package.json:项目核心的配置文件
  • src/extension.ts:程序代码文件(入口)
  • tsconfig.json:TypeScript配置文件(TypeScript会被编译成JavaScript来运行)

package.json文件

json
{
  "name": "HelloWorldID", // 插件ID
  "displayName": "Hello world", // 插件名称
  "description": "",
  "version": "0.0.1",
  "engines": {
    // 插件支持的VSCode版本
    "vscode": "^1.80.0" // 1.80.0及以上
  },
  "categories": [
    // 插件分类: 用来在插件市场分类
    "Other"
  ],
  "activationEvents": [], // 插件激活事件
  "main": "./out/extension.js", // 程序入口
  "contributes": {
    // 插件核心配置
    "commands": [
      // 插件命令: 用来注册命令(ctrl + shift + p)
      {
        "command": "runner.helloWorld", // 命令ID (代码中使用)
        "title": "Hello World" // 命令名称(用户使用)
      }
    ]
  },
  "scripts": {
    // npm脚本
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./",
    "pretest": "npm run compile && npm run lint",
    "lint": "eslint src --ext ts",
    "test": "node ./out/test/runTest.js"
  },
  "devDependencies": {
    // 开发依赖
    "@types/vscode": "^1.80.0",
    "@types/glob": "^8.1.0",
    "@types/mocha": "^10.0.1",
    "@types/node": "20.2.5",
    "@typescript-eslint/eslint-plugin": "^5.59.8",
    "@typescript-eslint/parser": "^5.59.8",
    "eslint": "^8.41.0",
    "glob": "^8.1.0",
    "mocha": "^10.2.0",
    "typescript": "^5.1.3",
    "@vscode/test-electron": "^2.3.2"
  }
}

Note:一些属性是正常的npm项目属性,有些属性是配置给VSCode插件用的

  • main属性:项目程序入口
  • contributes属性:VSCode插件核心配置节点(相对于VSCode插件来说)
  • activationEvents属性:激活插件的事件(方式)

src/extension.ts文件

ts
// 导入vscode模块
import * as vscode from 'vscode';

// 插件激活时调用
export function activate(context: vscode.ExtensionContext) {
  console.log('Congratulations, your extension "runner" is now active!');

  // 注册命令: runner.helloWorld
  let disposable = vscode.commands.registerCommand('runner.helloWorld', () => {
    // 显示一个信息框: Hello World from demo1!
    vscode.window.showInformationMessage('Hello World from demo1!');
  });

  context.subscriptions.push(disposable);
}

// 插件停用时调用
export function deactivate() {}
  • activate函数:插件激活时调用
  • deactivate函数:插件停用时调用

4. 编译、运行、调试

前面yo code命令已经生成了相应运行调试的配置,直接按 F5 键或VSCode的调试既可;配置文件列表:

  • .vscode/launch.json:调试配置
    • Run Extension:运行插件
    • Extension Tests:插件测试
  • .vscode/tasks.json:任务task配置

5. 打包、安装

bash
$ cd ${project_dir}

# 打包,会生成后缀为vsix的插件文件
$ vsce package

# 发布(我们自已用,不用公开发布)
$ vsce publish

安装:把生成的vsix文件拖拽到VSCode的插件列表中,安装既可

VSCode能力

大白话说:VSCode暴露了哪些接口(能力),让我们/开发者去利用(发挥):

  • Common Capabilities:通用能力
  • Theming:主题
  • Declarative Language Features:声明性语言特性(后面详细讲)
  • Programmatic Language Features:编程语言特性(后面详细讲)
  • Workbench Extensions:工作台UI
  • UX Guidelines:交互设计指南
  • Debugging:调试

Common Capabilities

通用能力列表:

Theming主题

分类:

  • Color Theme:颜色主题
  • File Icon Theme:文件类型图标主题
  • Product Icon Theme:VSCode产品图标主题

Color Theme:颜色主题

image-20230721095540788

File Icon Theme:文件类型图标主题

image-20230721095555037

Product Icon Theme:VSCode产品图标主题

image-20230721095503809

Declarative Language Features && Programmatic Language Features

这两个后面讲

Workbench Extensions

开发者角度:

  • Views Containers:视图容器
  • Tree View:树视图
  • Webview:Web视图
  • Status Bar Item:状态栏
  • etc
image-20230724145859144

Debugging调试

// TODO: 暂时用不上

插件开发指南

UX交互设计指南

  • Activity Bar:活动栏
  • Panel:面板
  • Status Bar:状态栏
  • Views:视图
  • Editor Actions:编辑器动作,编译运行
  • Context Menus:上下文菜单
  • Walkthroughs:步骤、流程性的操作(比如:环境配置、图片添加处理、字体添加处理...)

Panel

  • 串口连接:日志输出
  • 设备日志输出:级别过滤、正则过滤
image-20230721110609993

Status Bar

  • 和设备的链接状态
image-20230721112137524

View视图

  • 显示布局Layout.json 控件大纲(格式:控件类型-ID-src/text)
image-20230721110136943

Editor Actions

  • 固件编译、固件烧录
  • 程序编译运行、调试
image-20230721110010945

Context Menus

  • UI预览模式打开
  • UI编辑模式打开
image-20230721105708022

Walkthroughs

一步步跟着步骤走来去熟悉一个流程或概念;适合用于步骤、流程性的操作:

  • 环境配置
  • 图片添加处理
  • 字体添加处理
  • 用于排错,可以一步步去检查确认
  • etc
image-20230721105551780

语言拓展

  • Declarative language features:声明性语言特性(基础),通过写配置文件就实现了

  • Programmatic language features:编程语言特性(高级)(自动补全、错误检查、转跳到定义、查看引用),通过语言服务进程去实现

  • Language Server Protocol:语言服务协议(jsonRPC),可以用不同的语言来去实现这个服务进程,其它编辑器、IDE可以复用

Declarative language features

对编程语言提供基础的功能;能过写配置文件就能实现

  • Syntax highlighting:语法高亮
  • Snippet completion:代码片段补全
  • Bracket matching:括号匹配
  • Bracket autoclosing:括号补全
  • Bracket autosurrounding:
  • Comment toggling:注释
  • Auto indentation:自动缩进对齐
  • Folding (by markers):代码折叠

Snippet completion代码片段补全

示例:snippet-sample

  1. Snippets: Configure User Snippets去测试Snippets代码快
  2. 上一卡测试能用了,把文件拷贝到插件项目代码中,的json文件中,比如命名snippets.json
  3. package.json中添加snippets属性配置,如下
json
{
  "contributes": {
    "snippets": [
      {
        "language": "javascript",
        "path": "./snippets.json"
      }
    ]
  }
}

Language Configuration配置

示例:language-configuration-sample

package.json文件:languages下面的configuration属性

json
{
  // ...
  "categories": ["Programming Languages"],
  "contributes": {
    "languages": [
      {
        "id": "javascript",
        "extensions": [".js"],
        "aliases": ["js", "JavaScript"],
        "configuration": "./language-configuration.json"
      }
    ]
  }
}

language-configuration.json文件:

json
{
  "comments": {
    "lineComment": "//",
    "blockComment": ["/*", "*/"]
  },
  "brackets": [
    ["{", "}"],
    ["[", "]"],
    ["(", ")"]
  ],
  "autoClosingPairs": [
    { "open": "{", "close": "}" },
    { "open": "[", "close": "]" },
    { "open": "(", "close": ")" },
    { "open": "'", "close": "'", "notIn": ["string", "comment"] },
    { "open": "\"", "close": "\"", "notIn": ["string"] },
    { "open": "`", "close": "`", "notIn": ["string", "comment"] },
    { "open": "/**", "close": " */", "notIn": ["string"] }
  ],
  "autoCloseBefore": ";:.,=}])>` \n\t",
  "surroundingPairs": [
    ["{", "}"],
    ["[", "]"],
    ["(", ")"],
    ["'", "'"],
    ["\"", "\""],
    ["`", "`"]
  ],
  "folding": {
    "markers": {
      "start": "^\\s*//\\s*#?region\\b",
      "end": "^\\s*//\\s*#?endregion\\b"
    }
  },
  "wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)",
  "indentationRules": {
    "increaseIndentPattern": "^((?!\\/\\/).)*(\\{[^}\"'`]*|\\([^)\"'`]*|\\[[^\\]\"'`]*)$",
    "decreaseIndentPattern": "^((?!.*?\\/\\*).*\\*/)?\\s*[\\)\\}\\]].*$"
  }
}

属性下面一个个解释:

Comment toggling注释
json
{
  "comments": {
    "lineComment": "//",
    "blockComment": ["/*", "*/"]
  }
}
  • lineComment:行注释
  • blockComment:块注释
Brackets definition
  • VSCode语法高亮:括号高亮匹配
  • VSCode动作:转跳到括号**Go to Bracket**
  • VSCode动作:选择到括号**Select to Bracket**
json
{
  "brackets": [
    ["{", "}"],
    ["[", "]"],
    ["(", ")"]
  ]
}
Autoclosing

当输入open的字符,自动补全close的字符;notIn表示在某些场景下不生效,如字符串string、注释comment

json
{
  "autoClosingPairs": [
    { "open": "{", "close": "}" },
    { "open": "[", "close": "]" },
    { "open": "(", "close": ")" },
    { "open": "'", "close": "'", "notIn": ["string", "comment"] },
    { "open": "\"", "close": "\"", "notIn": ["string"] },
    { "open": "`", "close": "`", "notIn": ["string", "comment"] },
    { "open": "/**", "close": " */", "notIn": ["string"] }
  ]
}
Autoclosing before

正常情况下,输入光标后面有字符,自动结束标志就不会生效;autoCloseBefore属性,表示配置光标后面是这些符号也能生效

json
{
  "autoCloseBefore": ";:.,=}])>` \n\t"
}
Autosurrounding

当你选中一段代码,按下开始括号,会自动的在选中代码结束的地方加上结束括号

json
{
  "surroundingPairs": [
    ["{", "}"],
    ["[", "]"],
    ["(", ")"],
    ["'", "'"],
    ["\"", "\""],
    ["`", "`"]
  ]
}
Folding代码折叠

通过标记marker匹配规则

json
{
  "folding": {
    "markers": {
      "start": "^\\s*//\\s*#?region\\b",
      "end": "^\\s*//\\s*#?endregion\\b"
    }
  }
}
  • start:开始的匹配规则;匹配 //#region
  • end:结束的匹配规则;匹配//#endregion

示例代码:

js
console.log('foo');

// #region 折叠开始标记
console.log('bar');
console.log('foobar');

// #endregion 折叠结束标记

console.log('foobar');
Indentation Rules代码缩进规则
json
{
  "indentationRules": {
    "increaseIndentPattern": "^((?!\\/\\/).)*(\\{[^}\"'`]*|\\([^)\"'`]*|\\[[^\\]\"'`]*)$",
    "decreaseIndentPattern": "^((?!.*?\\/\\*).*\\*/)?\\s*[\\)\\}\\]].*$"
  }
}
  • increaseIndentPattern:增加缩进的匹配规则
  • decreaseIndentPattern:减少缩进的匹配规则

示例:if (true) {匹配到increaseIndentPattern规则,当按下回车Enter键之后,就会增加缩进

js
if (true) {
  console.log();

Programmatic language features

VSCode和插件充当一个客户端Client,VSCode的语言的功能通过专门的语言服务进程对其提供

  • Hover information:鼠标悬停显示相关信息
  • Auto completion:自动补全
  • Jump to definition:光标转跳到定义
  • Error checking:错误检查
  • Formatting:格式化
  • Refactoring:重构:修改symbols符号(函数、变量),使用到该symbols的都会被修改
  • Folding:代码折叠
image-20230721152435610

看文档:

Language Server Protocol

  • 标准化客户端与服务端交互流程,就制订了这个语言服务协议
  • 服务进程可以用不同的语言去实现
  • 复用:不同的编辑器、IDE可以利用通过语言服务协议来复用这些基础设施

https://microsoft.github.io/language-server-protocol/specification

image-20230724151720913

通过Clangd简单认识下协议、交互流程:

c代码示例:

c
#include <stdio.h>

/**
 * @brief foo 函数
 *
 */
void foo(void) {
    printf("foo\n");
}

int main(int argc, char* argv[]) {
    for (int idx = 0; idx < 10; idx++) {
        printf("hello world:[%d] \n", idx);
    }
    foo();
    return 0;
}
  • clangd启动
  • vscode和clangd的交互流程
  • 演示几个语言特性:

高级主题

// TODO

References详细文档

Updated at: