TL;DR

文章篇幅有点长 ,可以先收藏再看 。要是想直接看看怎么写一个扩展,直接去第二部分 ,或者直接去github看源码 。

第一部分 --- Extension 知识点

一、扩展的启动

  1. 如何保证性能 --- 扩展激活(Extension Activation) 我们会往VS Code中安装非常多的扩展,VS Code是如何保证性能的呢? 在VS Code中有一个扩展激活(Extension Activation)的概念:VS Code会尽可能晚的加载扩展(懒加载),并且不会加载会话期间未使用的扩展,因此不会占用内存。为了完成扩展的延迟加载,VS Code定义了所谓的激活事件(activation events)。 VS Code根据特定活动触发激活事件,并且扩展可以定义需要针对哪些事件进行激活。例如,仅当用户打开Markdown文件时,才需要激活用于编辑Markdown的扩展名。
  2. 如何保证稳定性 --- 扩展隔离(Extension Isolation) 很多扩展都写得很棒 ,但是有的扩展有可能会影响启动性能或VS Code本身的整体稳定性。作为一个编辑器用户可以随时打开,键入或保存文件,确保响应性UI不受扩展程序在做什么的影响是非常重要的。 为了避免扩展可能带来的这些负面问题,VS Code在单独的Node.js进程(扩展宿主进程extension host process)中加载和运行扩展,以提供始终可用的,响应迅速的编辑器。行为不当的扩展程序不会影响VS Code,尤其不会影响其启动时间 。

四、Activation Events --- package.json

既然扩展是延迟加载(懒加载)的,我们就需要向VS Code提供有关何时应该激活什么扩展程序的上下文,其中比较重要的几个: - onLanguage:${language} - onCommand:${command} - workspaceContains:${toplevelfilename} - *

activationEvents.onLanguage

根据编程语言确定时候激活。比如我们可以这样:

"activationEvents": ["onLanguage:javascript"
]

当检测到是js的文件时,就会激活该扩展。

activationEvents.onCommand

使用命令激活。比如我们可以这样:

"activationEvents": ["onCommand:extension.sayHello"
]

activationEvents.workspaceContains

文件夹打开后,且文件夹中至少包含一个符合glob模式的文件时激活。比如我们可以这样:

"activationEvents": ["workspaceContains:.editorconfig"
]

当打开的文件夹含有.editorconfig文件时,就会激活该扩展。

activationEvents.*

每当VS Code启动,就会激活。比如我们可以这样:

"activationEvents": ["*"
]

五、Contribution Points --- package.json

其中配置的内容会暴露给用户,我们扩展大部分的配置都会写在这里: - configuration - commands - menus - keybindings - languages - debuggers - breakpoints - grammars - themes - snippets - jsonValidation - views - problemMatchers - problemPatterns - taskDefinitions - colors

contributes.configuration

在configuration中配置的内容会暴露给用户,用户可以从“用户设置”和“工作区设置”中修改你暴露的选项。 configuration是JSON格式的键值对,VS Code为用户提供了良好的设置支持。 你可以用vscode.workspace.getConfiguration('myExtension')读取配置值。

contributes.commands

设置命令标题和命令,随后这个命令会显示在命令面板中。你也可以加上category前缀,在命令面板中会以分类显示。

注意:当调用命令时(通过组合键或者在命令面板中调用),VS Code会触发激活事件onCommand:${command}。

六、package.json其他比较特殊的字段

  • engines:说明扩展程序将支持哪些版本的VS Code
  • displayName:在左侧显示的扩展名
  • icon:扩展的图标
  • categories:扩展所属的分类。可以是:Languages, Snippets, Linters, Themes, Debuggers, Formatters, Keymaps, Other

第二部分 --- 自己写个扩展玩玩

我们经常使用console.log来打印日志进行调试,我们就写一个用来美化、简化console.log的扩展玩玩。最终实现的效果:

special-console-log

实现这个扩展,需要注意以下几点: 1. console.log使用css样式 2. VS Code插入内容 3. VS Code光标和选区 4. VS Code删除内容 5. VS Code读取用户配置

下面火速实操(p≧w≦q)。

如何开始

要开始写VS Code扩展,需要两个工具:

  • yeoman:有助于启动新项目
  • vscode-generator-code:由VS Code团队使用yeoman构建的生成器 可以使用yarn或npm安装这两个工具,安装完成之后执行yo code,等一会之后它会帮我们生成起始项目,并会询问几个问题:

确认信息之后,会帮我们初始化好整个项目,此时的目录结构是这样的:

我们只需要关注src/extension.tspackage.json即可,其中package.json里面的内容之前已经介绍过。

console.log使用css样式

这里有一篇比较完整的文章:https://www.telerik.com/blogs/how-to-style-console-log-contents-in-chrome-devtools 简单的说,这句代码执行之后打印的是下面图片那样console.log("%cThis is a green text", "color:green");:

后面的样式会应用在%c后面的内容上

vscode扩展读取用户配置

上文提到过,我们可以在contributes里面定义用户配置:

"contributes": {"configuration": {"type": "object","title": "Special-console.log","properties": {"special-console.log.projectName": {"type": "string","default": "MyProject","description": "Project name"},"special-console.log.showLine": {"type": "boolean","default": true,"description": "Show line number"},"special-console.log.deleteAll": {"type": "boolean","default": false,"description": "delete all logs or delete the log containing [color] and [background]"}}}
},

然后使用vscode.workspace.getConfiguration()读取用户配置

激活扩展

前面提到扩展是延迟加载(懒加载)的,我们只需要向VS Code提供有关何时应该激活什么扩展程序的上下文即可。我们在package.json中定义两个激活的事件:

"activationEvents": ["onCommand:extension.insertLog","onCommand:extension.deleteLogs"
],

接着在contributes中添加快捷键:

"keybindings": [{"command": "extension.insertLog","key": "shift+ctrl+l","mac": "shift+cmd+l","when": "editorTextFocus"},{"command": "extension.deleteLogs","key": "shift+ctrl+d","mac": "shift+cmd+d"}
],

还可以将命令添加到命令面板里面,也就是按Ctrl +Shift+P弹出来的面板:

"commands": [{"command": "extension.insertLog","title": "Insert Log"},{"command": "extension.deleteLogs","title": "Delete console.log"}
],

insertLog表示往内容中插入console.logdeleteLogs则表示删除。具体的实现我们放到src/extension.ts的activate中:

export function activate(context: vscode.ExtensionContext) {const insertLog = vscode.commands.registerCommand('extension.insertLog', () => {})context.subscriptions.push(insertLog)const deleteLogs = vscode.commands.registerCommand('extension.deleteLogs', () => {})context.subscriptions.push(deleteLogs)
}

插入console.log

  1. 插入console.log 大概的过程是获取当前选区的内容,获取用户配置,根据用户配置和当前选区的内容填充console.log,最后插入到选区的下一行。
const insertLog = vscode.commands.registerCommand('extension.insertLog', () => {const editor = vscode.window.activeTextEditorif (!editor) { return }const selection = editor.selectionconst text = editor.document.getText(selection) // 当前选区内容// 用户配置if (userConfig) {projectName = userConfig.projectName || projectNameshowLine = userConfig.showLine || showLineline = showLine?`%cline:${lineNumber}`:'%c'}// 设置console.log...// 在下一行插入vscode.commands.executeCommand('editor.action.insertLineAfter').then(() => {insertText(logToInsert, !text, noTextStr.length)})})

插入内容:

const insertText = (val: string, cursorMove: boolean, textLen: number) => {const editor = vscode.window.activeTextEditorif (!editor) {vscode.window.showErrorMessage('Can't insert log because no document is open')return}editor.edit((editBuilder) => {editBuilder.replace(range, val) // 插入内容}).then(() => {// 修改选区})
}

删除console.log

删除的时候只需要遍历找一下console.log在判断一下是不是我们加入的内容,是就删除

const deleteLogs =      vscode.commands.registerCommand('extension.deleteLogs', () => {const editor = vscode.window.activeTextEditorif (!editor) { return }const document = editor.documentconst documentText = editor.document.getText()let workspaceEdit = new vscode.WorkspaceEdit()// 获取logconst logStatements = getAllLogs(document, documentText)// 删除deleteFoundLogs(workspaceEdit, document.uri, logStatements)})

删除的时候可以使用workspaceEdit.delete(docUri, log),当然,删除之后我们可以右下角搞个弹窗提示一下用户删除了几个console.log

vscode.workspace.applyEdit(workspaceEdit).then(() => {vscode.window.showInformationMessage(`${logs.length} console.log deleted`)
})

具体的代码可以看看github

发布

这个就注册一下账号然后发布就行

vscode弹出cmd_先看看 VS Code Extension 知识点,再写个 VS Code 扩展玩玩相关推荐

  1. 弹出框口登录php代码,如何用JQuery写出登录弹出框

    类似百度的登录弹出框,可用jquery的fadeIn(),hide(),show(),slideDown()等动画函数实现,一下为html5 代码: $(document).ready(functio ...

  2. vue之表格数据渲染,实现点击表格某列按钮弹出框显示剩余数据(模态框知识点)

    点击按钮弹出模态框实现详情:https://blog.csdn.net/qq_20565303/article/details/78734592 结果: 代码: <template>< ...

  3. Win7交互式服务编程,不弹出交互式服务检测

    第一次写Windows服务程序,XP下一个MessageBox都弹不出来,在Services.msc中允许其与桌面交互后,MessageBox就能正常弹出.但在Win7下总是弹出[Windows交互式 ...

  4. 九种js弹出对话框的方法

    [1.最基本的js弹出对话框窗口代码] 这是最基本的js弹出对话框,其实代码就几句非常简单: 复制代码代码如下: <script LANGUAGE="javascript"& ...

  5. html js弹出等待框,九种js弹出对话框的方法总结

    [1.最基本的js弹出对话框窗口代码] 这是最基本的js弹出对话框,其实代码就几句非常简单: 因为这是一段javascripts代码,所以它们应该放在之间.是对一些版本低的浏览器起作用,在这些老浏览器 ...

  6. showimg.php,layer弹出图片

    layer弹出层非常之好用,用户体验非常好,有这样一个需求,当点击指定文字或是缩略图后,使用layer弹出原图片,并且弹出层的宽和高根据图片大小自动变化.下面是实现这一功能的代码.function s ...

  7. python电脑下载有问题-Python 解决火狐浏览器不弹出下载框直接下载的问题

    用火狐浏览器下载文件,总是遇到这个弹窗问题,如下图: 原因: 使用火狐浏览器,点击下载,弹出下载弹框,使用AutoITLibrary库,能够判断是否弹出了下载弹框,但因为不能定位到下载弹框,导致没有下 ...

  8. html弹出窗口加载别的页面地址,仿layer.open打开新窗口URL,自适应URL页面高度

    layer.open打开新窗口URL,不能在弹出窗口的同时根据所打开URL地址页面的大小,弹出的同时自适应窗口大小,所以根据需要自己写了一个,请参考指正. 首先加载jquery 下面是js代码: // ...

  9. 自动弹窗被拦截 html,弹出式窗口被阻止怎么办,如何阻止弹出式窗口

    很多人看到"弹出式窗口"这个名词时想必会有所疑惑,弹出与固定式窗口究竟有何不同呢?其实我们在浏览网页的时候就会发现许多弹出式窗口,这种窗口主要应用于广告类,许多商家会为各种大小网页 ...

最新文章

  1. stl_config.h基本宏
  2. 二层交换机、三层交换机与路由器的比较
  3. 你不知道的 JavaScript 笔记——作用域和闭包
  4. 买股票的最佳时机(六种题解dp)
  5. OpenCASCADE:使用 XSTEPDRAW
  6. 见微知著(一):解析ctf中的pwn--Fast bin里的UAF
  7. Flink中的容错机制
  8. 【Flink】Flink的 processingTimeTimersQueue 是如何注册数据的
  9. Android 程序目录介绍
  10. java界面中加载图片,Java登录界面中添加背景图片,程序无错,但加载不了图片,求帮忙...
  11. VisualStudio 2010从分析到实施(3)——使用Use Case Diagram设计系统交互
  12. 装箱拆箱的意义 java_Java中的装箱和拆箱深入理解
  13. 2.70-写出具有如下原型的函数的代码:
  14. 5种Python深度学习库和资料
  15. 2021年T电梯修理免费试题及T电梯修理考试试卷
  16. 河北专升本经验总结分享
  17. 超级光棍节,你想好怎么过了吗?来聆听大师的演讲吧
  18. 极限和连续+偏导+方向导数+可微+梯度+链式法则+hessian矩阵
  19. python绘制一个时间的七段数码管实例基本的七段数码管绘制
  20. pde与波长 sipm 关系_基于SiPM和TCMPC的时间分辨拉曼散射测量技术研究

热门文章

  1. 基于JavaSwing+mysql的图书管理系统设计和实现
  2. mysql 主表存hash和子表的名字_【mysql】mysql分表和表分区详解
  3. 一张纸厚度是多少毫米_一张纸的威力有多大?纸折103次捅破宇宙,理论荒诞却无法反驳...
  4. php的功能和特点,php的特点有哪些
  5. C语言exchange函数,C++指针作为函数参数
  6. Java 获取文件修改时间
  7. MySQL 删除视图
  8. Spring目录结构和基础JAR包介绍
  9. word2016能识别linux换行符,word文章中的换行符如何批量替换为回车符
  10. python音频聚类_python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)