示例:Hello World

你的第一个插件


本节通过Hello World这个完整的项目手把手教你掌握VS Code扩展性概念。 在本项目中,我们会给VS Code添加一个新的命令,虽然只是用来显示”Hello World”信息。在本节的最后,你将和编辑器编辑器互动,查找用户选中的文本。

预备工作

请查看生成插件-预备工作

生成新插件

请查看生成插件-运行Yo

运行插件


  • 打开VS Code,选择文件>打开文件夹,选择你刚刚生成的项目目录
  • 点击F5或者Debug按钮,然后点击开始
  • 新的VS Code实例会运行在特殊环境中(Extension Development Host
  • 按下⇧⌘P(windows shift + ctrl + p),输入命令Hello world
  • 恭喜!你的第一个VS Code插件执行成功了

示例:Hello-World - 图1

插件的目录结构


构建完毕之后,你的插件开发目录看起来应该是这样的

  1. .
  2. ├── .gitignore
  3. ├── .vscode // VS Code 文件
  4. ├── launch.json
  5. ├── settings.json
  6. └── tasks.json
  7. ├── .vscodeignore // 发布插件时忽略的文件
  8. ├── README.md
  9. ├── src
  10. └── extension.ts // 插件的入口(源文件)
  11. ├── test // 测试文件夹
  12. ├── extension.test.ts // extension.test.js, 如果是 JavaScript 插件的话
  13. └── index.ts // index.js, 如果是 JavaScript 插件的话
  14. ├── node_modules
  15. ├── vscode // 包含了vscode插件开发时的类型定义文件
  16. └── typescript // typescript的编译器 (TypeScript only)
  17. ├── out // 编译出口 (TypeScript only)
  18. ├── extension.js // 插件入口
  19. ├── extension.js.map
  20. └── test
  21. ├── extension.test.js
  22. ├── extension.test.js.map
  23. ├── index.js
  24. └── index.js.map
  25. ├── package.json // 插件清单
  26. ├── tsconfig.json // jsconfig.json, 如果是 JavaScript 插件的话
  27. └── vsc-extension-quickstart.md // 快速上手插件开发

让我们看看这些文件夹都是干什么用的:

插件清单:package.json

  • 每个VS Code插件都有package.json文件,文件内包含了这个插件功能和用处。
  • 当项目启动时,VS Code会立即读取这个文件中的每个配置(contributes)部分并作出响应。
  • 请阅读package.json插件清单参考文档
  • 更多信息请参阅package.json发布内容配置参考文档

?> 译者注:为了便于理解,contribution / contributes在本教程中译为发布内容配置/配置contribution points译为发布内容配置点/配置点

示例:基于TypeScript的pacakge.json

  1. {
  2. "name": "myFirstExtension",
  3. "description": "",
  4. "version": "0.0.1",
  5. "publisher": "",
  6. "engines": {
  7. "vscode": "^1.5.0"
  8. },
  9. "categories": [
  10. "Other"
  11. ],
  12. "activationEvents": [
  13. "onCommand:extension.sayHello"
  14. ],
  15. "main": "./out/extension",
  16. "contributes": {
  17. "commands": [{
  18. "command": "extension.sayHello",
  19. "title": "Hello World"
  20. }]
  21. },
  22. "scripts": {
  23. "vscode:prepublish": "tsc -p ./",
  24. "compile": "tsc -watch -p ./",
  25. "postinstall": "node ./node_modules/vscode/bin/install",
  26. "test": "node ./node_modules/vscode/bin/test"
  27. },
  28. "devDependencies": {
  29. "typescript": "^2.0.3",
  30. "vscode": "^1.5.0",
  31. "mocha": "^2.3.3",
  32. "@types/node": "^6.0.40",
  33. "@types/mocha": "^2.2.32"
  34. }
  35. }

!> 提示: 基于JavaScript的插件没有scripts部分,因为不需要编译。

这份package.json文件说了什么呢?

  • 配置部分(contributes)命令面板定义了一个叫做Hello world的入口,它会调用’extension.sayHello’。
  • 当命令”extension.sayHello”调用时,执行loaded(激活事件)请求。
  • 在”./out/extension.js“中,存放着我们的主文件。

!> 注意:VS Code 不会一启动就加载插件。插件必须在activationEvents中描述它的启动时机,比如loaded事件。

生成的代码

自动生成的代码存放在extension.ts(或者extension.js中)。

  1. // 'vscode'模块包含了VS Code extensibility API
  2. // 按下述方式导入这个模块
  3. import * as vscode from 'vscode';
  4. // 一旦你的插件激活,vscode会立刻调用下述方法
  5. export function activate(context: vscode.ExtensionContext) {
  6. // 用console输出诊断信息(console.log)和错误(console.error)
  7. // 下面的代码只会在你的插件激活时执行一次
  8. console.log('Congratulations, your extension "my-first-extension" is now active!');
  9. // 入口命令已经在package.json文件中定义好了,现在调用registerCommand方法
  10. // registerCommand中的参数必须与package.json中的command保持一致
  11. let disposable = vscode.commands.registerCommand('extension.sayHello', () => {
  12. // 把你的代码写在这里,每次命令执行时都会调用这里的代码
  13. // ...
  14. // 给用户显示一个消息提示
  15. vscode.window.showInformationMessage('Hello World!');
  16. });
  17. context.subscriptions.push(disposable);
  18. }
  • 每个插件都应该在主文件中注册一个activate()函数,因为这个函数只会调用一次。你只有在package.json中注册了activationEvents列表中的事件,激活事件才会被调用。
  • 如果插件使用了系统资源(如:生成进程),则需要从主文件中导出名为deactive()的函数去清理释放这些资源,VS Code会在关闭时调用这个方法。
  • 这个插件导入了VS Code API,然后注册了”extension.sayHello”命令和回调函数,执行后在VS Code中显示一条”Hello World!”消息。

!> 注意: package.jsoncontributes部分给命令面板添加了一个调用入口。extension.ts/.js定义了extension.sayHello的实现。对于 Typescript类型的插件来说,生成的out/extension.js会在运行时加载。

其他文件

  • vscode/launch.json 告诉VS Code启用插件开发模式。它也描述了.vscode/tasks.json中需要Typescript编译器的预加载任务。
  • vscode/settings.json 默认排除外部文件夹。你如果想隐藏一些文件,可以修改这个配置。
  • gitignore - 告诉git不跟踪哪些文件。
  • vscodeignore - 告诉打包工具,发布插件时应该忽略哪些文件。
  • README.md - 为插件的使用用户提供良好的文档。
  • vsc-extension-quickstart.md - 你的快速开始指南。
  • test/extension.test.ts - 把你的单元测试放在这里,看看和VS Code API有哪些出入。

    插件激活过程


我们刚刚已经了解了开发目录下的每个文件,现在我们看看你的插件是怎么运行起来的:

  1. 插件开发环境发现了这个插件,然后读取它的package.json
  2. 你按下ctrl shift p时,命令面板显示出已注册的命令列表
  3. 在列表中你找到package.json中定义的Hello world命令入口
  4. 选中并执行Hello world,随即执行真实的”extension.sayHello“命令
    • 创建"onCommand:extension.sayHello"激活事件
    • 激活所有注册在activationEvents的事件
      • Javascript虚拟机加载./out/extension.js文件
      • VS Code查找导出的activate函数,并调用
  5. 调用"extension.sayHello"注册的函数
  6. 函数执行,显示出”Hello world”消息

    调试插件


直接在你的代码里打上断点就可以调试了,很简单吧。

调试

!> 注意:VS Code具有解析sourcemap的能力,所以你可以直接在Typescript代码中调试。

?>小提示:调试控制台(Debug Console)能输出所有console打印的日志。

查看更多关于插件开发环境的东西。

小小的改造


试着修改你的extension.ts(或者extension.js)中extension.sayHello的实现,我们把它改造成一个对选中文本计数的功能。

  1. let disposable = vscode.commands.registerCommand('extension.sayHello', () => {
  2. // 每当你执行命令,这里的代码都会执行一次
  3. let editor = vscode.window.activeTextEditor;
  4. if (!editor) {
  5. return; // 没有打开的编辑器
  6. }
  7. let selection = editor.selection;
  8. let text = editor.document.getText(selection);
  9. // 给用户一个消息提示框
  10. vscode.window.showInformationMessage('Selected characters: ' + text.length);
  11. });

!> 当你修改了代码,你需要按Ctrl + R(macOS Cmd + R)重启Extension Development Host,或者直接按VS Code上面的重启按钮

新建一个文件,输入一些文本然后选中。当你运行Hello World命令,你应该能看到字符计数的消息框。

文字计数

在本地安装你的插件


好了,现在你已经完成了一个运行在开发模式下的插件,为了让你的插件运行在所有VS Code实例中,你需要在本地插件目录下新建一个文件夹,然后复制过去:

  • Windows: %USERPROFILE%\.vscode\extensions
  • macOS/Linux: $HOME\.vscode\extensions

发布插件


参阅分享插件

下一步


在本篇指引中,我们实现了一个小小的插件。在示例-Word Count中你能找到完整的例子,学习如何在Markdown文件中监听编辑器的文档变动事件、显示文本字数。

如果你想查看更多extension API的概述,看看这些主题吧: