相关文章推荐
怕老婆的卤蛋  ·  C# 基本语法 | ·  1 月前    · 
风流的手术刀  ·  ios - fwrite(): SSL ...·  1 年前    · 

这是我参与8月更文挑战的第4天,活动详情查看: 8月更文挑战

HBuilderX 2.7+版本起,开放了插件扩展机制。开发者可以通过 JavaScript 语言编写HBuilderX的插件,自定义和增强HBuilderX,打造更趁手的利器。

插件扩展能做什么?

HBuilderX的插件是基于nodejs的,所有nodejs api都可以使用,如文件操作、调用其他node命令。

除此之外,HBuilderX提供了大量的js API(与vscode兼容),可以定制很多HBuilderX的功能和界面,比如

  • 添加新的 菜单
  • 添加新的 命令 及快捷键
  • 扩展新的 代码块
  • 添加新的view 视图 ,比如在界面左侧项目管理器旁边新增加一个“TODO”视图
  • 对文档进行各种编辑,增删改文字内容、操作光标和选区
  • 对文档进行校验
  • 在控制台打印日志、操作状态栏消息、弹出各种提示框和选择框
  • 注意:插件是运行在单独的 插件进程 内的, 插件进程 是一个node.js进程,通过进程间rpc通信和HBuilderX进行接口调用。因此插件可以使用node本身所有的api。目前集成的node版本为:v8.10.0。

    新建插件扩展

    在HBuilderX里通过工具栏上 新建 按钮或者快捷键 ctrl+n 打开新建菜单选择 项目 ,如下图所示,选择 普通项目 - 插件扩展开发

    注意:插件名称只能用英文字母和数字,不支持中文和空格。

    建好插件项目后,选中该项目或者打开项目下某个文件,然后点击工具栏上 运行 按钮或者快捷键 ctrl+r 打开运行菜单,选择 运行插件xxx 即可新开一个HBuilderX窗体,这个新窗体将自动载入该插件。如下图

    运行起来的效果图如下:

    插件扩展开发模板示例中在代码编辑器右键菜单上注册了一个 Hello World 菜单, 此时我们打开一个文档 ,然后右键即可看到 Hello World 菜单。点击该菜单运行后会在窗口显示一个提示框。如下图

    也就是在老窗体写插件代码,保存插件代码后,在新窗体预览效果。

    修改插件代码后需要重新运行插件

    运行起来的插件,在老窗体的控制台,会打印日志。

    开发者可以使用 console.log console.error 等API,把信息打印到老窗体的调试控制台。

    插件代码说明

    package.json

    package.json在每个插件中都必须存在,包含插件的信息和 配置扩展点 。以下是示例插件的package.json代码说明

    //注意,不能直接拷贝本段代码到编辑器中,package.json目前不支持注释。本段代码加的注释只是用于解释代码。 //插件名称,必填字段 "name" : "your extension name" , "description" : "your extension description" , //插件版本号,用于版本升级判断,必填字段 "version" : "0.0.0" , "publisher" : "your name" , //需要的最低HBuilder版本号,必填字段 "engines" : { "HBuilderX" : "^2.6.8" //插件分类 "categories" : [ "Other" //插件的程序入口js文件,在插件激活的时候调用 "main" : "./extension" , //插件激活事件注册,当以下事件发生时,才会激活插件。 "activationEvents" : [ //onCommand表示将要执行某个command的时触发该事件,本示例表示只有要执行`extension.helloWorld`的`命令`时本插件才会激活 "onCommand:extension.helloWorld" //配置扩展点 "contributes" : { //`命令`扩展点,用于声明一个`命令`,所有扩展的`命令`必须通过该扩展点声明 "commands" : [ { //`命令`唯一标识 "command" : "extension.helloWorld" , //`命令`的名称,当关联到菜单时,如果未配置菜单名称,会用该名称。 "title" : "Hello World" } ] , //`菜单`扩展点,用于注册一个`菜单` "menus" : { //编辑器右键菜单 "editor/context" : [ //关联的`命令`唯一标识 "command" : "extension.helloWorld" , //注册到菜单的位置 "group" : "z_commands" , //在什么条件下显示 "when" : "editorTextFocus" //不关联`命令`的菜单扩展代表一个分割线 "group" : "z_commands" "dependencies" : { }

    插件入口文件

    本示例的插件入口文件是extension.js,插件入口文件必须要exports activate 方法,该方法在插件激活的时候调用。代码说明如下:

    var hx = require("hbuilderx");
    //该方法将在插件激活的时候调用
    function activate(context) {
        let disposable = hx.commands.registerCommand('extension.helloWorld', () => {
            hx.window.showInformationMessage('你好,这是我的第一个插件扩展。');
            console.log("Hello My First HBuilderX Extension.");
        //订阅销毁钩子,插件禁用的时候,自动注销该command。
        context.subscriptions.push(disposable)
    //该方法将在插件禁用的时候调用(目前是在插件卸载的时候触发)
    function deactivate() {
    module.exports = {
        activate,
        deactivate
    

    其他插件示例

    hbuilderx-extension-samples

    插件扩展分为2个部分,分别为插件API配置扩展点

    插件API说明

    HBuilderX的插件是运行在单独的node.js进程的。除了调用HBuilderX提供的API列表外,node.js支持的API也能调用。当前开放的插件API列表参考这里

    配置扩展点说明

    配置扩展点是通过在插件描述文件package.json下的contributes节点下注册的配置。这里有完整的配置扩展点列表。

    为什么引入配置扩展点的概念?

    HBuilderX对性能要求很高,配置扩展点也是出于性能考虑。 用户在安装插件时,每多安装一个插件都会额外增加主程序的启动加载时间,HBuilderX为了不影响主程序的启动时间,增加了插件懒加载的机制,即HBuilderX启动时不会自动激活已安装的插件,而只是解析插件的配置文件package.json里面的配置扩展点,通过配置扩展点添加插件想要注册的菜单命令配置等。当用户真正激活某个菜单或者命令时再通过onXXX事件去激活对应的插件。这样即满足了插件扩展的能力,又能减少对主程序性能的影响。关于懒加载的详细说明请参考插件激活机制

    如何注册命令

    命令指的是在插件中注册的自定义function,命令触发时将调用该function。注册一个新的命令分为2个步骤:

    1 . 在package.json中通过commands配置扩展点声明该命令,相关代码如下:

        "contributes": {
            "commands": [{
                "command": "extension.helloWorld",
                "title": "Hello World"
    

    2 . 在插件激活的时候通过API hx.commands.registerCommand或者hx.commands.registerTextEditorCommand来实现上面声明的命令,注意命令标识一定要一致。相关代码如下:

        let disposable = hx.commands.registerCommand('extension.helloWorld', () => {
                //do something
        context.subscriptions.push(disposable)
    

    如何注册菜单

    菜单扩展是通过配置扩展点来注册的,一般要关联一个命令。扩展方式是在package.json中contributes节点下增加menus扩展点。相关代码如下:

        "contributes": {
            "menus": {
                "editor/context": [
                        "command": "extension.helloWorld",
                        "group": "z_commands",
                        "when": "editorTextFocus"
                        "group": "z_commands"
    

    如何注册一个视图

    TreeView

    从HBuilderX 2.7.12及以上版本开始支持
    

    扩展一个新的 TreeView 视图(view)通过以下2个步骤:

  • 通过 viewContainersviews配置扩展点声明要扩展的视图
  • //package.json;
    //...NOTE:package.json不支持注释,以下代码使用时需要将注释删掉
    "contributes":{
      "viewsContainers":{
      "activitybar":[{
        "id":"demoview",
        "title":"DemoView"
    "views":{
        "demoview":[{
          //该id需要和window.createTreeView中的viewId参数一致
          "id":"extensions.treedemo",
          "name":"DemoView"
    
  • 在插件激活时通过API:window.createTreeView实现上面扩展的视图
  • // extension.js
    var hx = require("hbuilderx");
    classDemoTreeDataProvider extends hx.TreeDataProvider{
        constructor(demoData){
            super();
    this._demoData = demoData;
        getChildren(element){
            let demoData =this._demoData;
    returnnewPromise(resolve =>{
    if(!element){
                    resolve(demoData);
    }else{
                    resolve(element.children);
        getTreeItem(element){
    return{
                label:element.name,
                collapsibleState:element.children ?1:0,
                command:{
                    command:element.children ?"":"extension.helloWorld",
                    arguments:[
                        element.name
    //该方法将在插件激活的时候调用
    function activate(context){
        let demoData =[
                name:"Root1",
                children:[
                        name:"child1"
                        name:"child2"
                name:"Root2",
                children:[
                        name:"child3",
                        name:"child4"
        hx.commands.registerCommand("extension.helloWorld",function(param){
            hx.window.showInformationMessage("选中了TreeItem:"+ param[0]);
        hx.window.createTreeView("extensions.treedemo",{
            showCollapseAll:true,
            treeDataProvider:newDemoTreeDataProvider(demoData)
    //该方法将在插件禁用的时候调用(目前是在插件卸载的时候触发)
    function deactivate(){
    module.exports ={
        activate,
        deactivate
    

    扩展后的视图可通过菜单视图-显示扩展视图打开

    WebView

    从HBuilderX 2.8.1及以上版本开始支持
    

    扩展一个新的 WebView 视图(view)通过以下2个步骤:

  • 通过viewContainersviews配置扩展点声明要扩展的视图
  • //package.json;
    //...NOTE:package.json不支持注释,以下代码使用时需要将注释删掉
    "contributes":{
      "viewsContainers":{
      "rightside":[{
      "id":"WebViewcontainerId",
      "title":"webview 展示"
    "views":{
    "WebViewcontainerId":[{
    "id":"extension.WebView",
    "title":"webview - 展示"
    
  • 在插件激活时通过API:window.createWebView实现上面扩展的视图
  • const hx = require('hbuilderx');
     * @description 显示webview
    function showWebView(webviewPanel){
        let webview = webviewPanel.WebView;
    var background ='';
        let config = hx.workspace.getConfiguration();
        let colorScheme = config.get('editor.colorScheme');
    if(colorScheme =='Monokai'){
            background ='rgb(39,40,34)'
    }elseif(colorScheme =='Atom One Dark'){
            background ='rgb(40,44,53)'
    }else{
            background ='rgb(255,250,232)'
        webview.html =
    <body style="background-color:${background};border:1px solid ${background};">
    <div style="max-width:200px;">
    <img src="https://download1.dcloud.net.cn/uploads/images/hbuilderx/hx_desc@1x.png" style="position: absolute;bottom: 0;left: 0;right: 0;width: 100%;margin: auto;">
    <script>
    //    以下两种写法等同
                    hbuilderx.onDidReceiveMessage((msg)=>{});
                    window.addEventListener("message",(msg)=>{});
                    hbuiderx.postMessage({
                        command:'alert',
                        text:'HelloWorld'
    </script>
    </body>
        webview.postMessage({
            command:"test"
        webview.onDidReceiveMessage((msg)=>{
    if(msg.command =='alert'){
                hx.window.showInformationMessage(msg.text);
    module.exports ={
        showWebView
    

    1 . 通过hx.window.getActiveTextEditor()

    代码如下:

        let editorPromise = hx.window.getActiveTextEditor();
        editorPromise.then((editor)=>{
            let document = editor.document;
            let selection = editor.selection;
            // Get the word within the selection
            let word = document.getText(selection);
            let reversed = word.split('').reverse().join('');
            editor.edit(editBuilder => {
                editBuilder.replace(selection, reversed);
    

    2 . 通过编辑器命令,hx.commands.registerTextEditorCommand(‘id’,(editor)=>{});

    代码如下:

    hx.commands.registerTextEditorCommand('extension.reverseSelectWord',(editor)=>{
        let document = editor.document;
        let selection = editor.selection;
        // Get the word within the selection
        let word = document.getText(selection);
        let reversed = word.split('').reverse().join('');
        editor.edit(editBuilder => {
            editBuilder.replace(selection, reversed);
    

    如何写一个校验器

    对文件进行验证有3种触发方式:

  • 通过点击注册的某个菜单触发验证
  • 监听文档修改事件实时验证
  • 监听文档保存事件验证
  • 将验证的错误列表发送到HBuilderX进行显示的代码如下:

    let editorPromise = hx.window.getActiveTextEditor();
    editorPromise.then((editor)=>{
        let doc = editor.document;
        //do validation document。
        //doValidateDocument(doc);
        let diagnositics = hx.languages.createDiagnosticCollection('validation name');
        diagnositics.set(doc.uri,[
                column: 0,
                line: 0,
                message: 'a error message.'
    

    发布与安装

    在插件市场发布

    HBuilderX插件发布,在DCloud统一的插件市场,ext.dcloud.net.cn/。

  • 在插件市场页面右上角,点击发布插件。(如未注册,需注册登录)
  • 在发布插件页面,选择插件分类为HBuilderX,然后按要求填写表单发布即可
  • 插件使用者可以在插件市场web界面进行插件安装。

    离线安装插件

    该插件拷贝到HBuilderX的安装目录/plugins下,然后重启HBuilderX即可生效。

    开发者如果在内网环境,可以先在外网环境点击插件市场web界面的下载zip插件,把zip包放入内网环境,解压到HBuilderX目录使用。

    API文档

    HBuilderX API根对象可以通过require(‘hbuilderx’)引入。

    const hx = require('hbuilderx')
    

    以下列出目前可用的API列表

    commands

    commands二级模块对象,用于处理和命令相关的逻辑。命令包含2部分:唯一ID和自定义的function,可以通过registerCommand或registerTextEditorCommand注册。命令可以通过以下方式触发:

    菜单:将命令通过menus扩展点关联到某个菜单。

    通过commands扩展点声明一个command,然后关联到menus

    "contributes":{ "commands":[ "command":"extension.firstExtension", "title":"My First Extension" "menus":{ "editor/context":[ "command": "extension.firstExtension", "group": "z_commands", "when": "editorTextFocus"

    在插件的激活回调(activate)中注册该command

    hx.commands.registerCommand('extension.firstExtension',()=>{
     hx.window.showInformationMessage("Hello My First Extension.");
    

    用户自定义快捷键:使用插件的用户可以通过得知命令的ID(一般在package.json中有声明),然后通过自定义快捷键配置一个快捷键。

    // Keybindings.json;
          "key":"ctrl+shift+0",
          "command":"extension.firstExtension"
    

    executeCommand

    执行指定id的命令。除了插件扩展的命令外,还可以执行HBuilderX内置的命令,完整的内置命令列表可以通过HBuilderX的顶部菜单工具-自定义快捷键,然后在打开的配置文件左侧部分找到所有列出的command字段

    //执行插件扩展的命令
    hx.commands.executeCommand('extension.firstExtension')
    //执行内置的命令(关闭所有打开的编辑器)
    hx.commands.executeCommand('workbench.action.closeAllEditors')
    

    registerCommand

    注册一个指定id的命令,并关联一个自定义的函数

    返回类型描述
    Disposable命令的销毁器,可将该对象放置到插件的context.subscriptions数组内,插件卸载时,将会自动注销该命令
        let disposable = hx.commands.registerCommand('extension.firstExtension',()=>{
            hx.window.showInformationMessage("Hello My First Extension.");
        context.subscriptions.push(disposable);
    

    registerTextEditorCommand

    注册一个指定id的编辑器命令

    返回类型描述
    Disposable命令的销毁器,可将该对象放置到插件的context.subscriptions数组内,插件卸载时,将会自动注销该命令
        let disposable = hx.commands.registerTextEditorCommand('extension.firstExtension',(editor)=>{
            hx.window.showInformationMessage(editor.document.fileName);
        context.subscriptions.push(disposable);
    

    languages

    languages二级模块对象,用于处理和编程语言相关的逻辑,目前仅支持校验文档时创建问题列表。

    createDiagnosticCollection

    创建一个问题列表,可用于文档校验时在文档出错区域显示波浪线标识问题。

    返回类型描述
    DiagnosticCollection创建的问题列表
        let activeEditor = hx.window.getActiveTextEditor();
        activeEditor.then(function(editor) {
            // 获取文件路径
            let file_url = editor.document.uri.fsPath;
            // 通过editor.document可以获取文档对象进行校验
            // 创建一个测试问题集合
            let collections = [{
                    column: 0,
                    line: 3,
                    message: "error for test",
                    severity: 'error'
            let diagnostics = hx.languages.createDiagnosticCollection('eslint');
            diagnostics.set(file_url, collections);
    

    window

    window二级模块对象,用于处理主窗口相关的逻辑。

    setStatusBarMessage

    设置HBuilderX底部状态栏消息

    参数名称参数类型描述
    textString消息内容
    hideAfterTimeoutNumber[可选] 多长时间后自动隐藏,单位ms,默认值是0:不自动隐藏
    levelString[可选] 消息级别,取值有[‘warn’,’info’,’error’],默认值:’info’
    返回类型描述
    Disposable销毁器,可调用dispose方法清理状态栏消息
    hx.window.setStatusBarMessage('正在校验xxx文档...',600,'info');
    

    clearStatusBarMessage

    清空状态栏消息

        hx.window.clearStatusBarMessage();
    

    showErrorMessage

    在窗口右下角显示错误通知框

    返回类型描述
    Promise如果设置了按钮,返回用户点击了哪个按钮
        let resultPromise = hx.window.showErrorMessage('是否删除该文件?',['是','否']);
        resultPromise.then((result)=>{
            if(result == '是'){
                console.log("选择了是");
            }else if(result === '否'){
                console.log("选择了否");
    

    showInformationMessage

    在窗口右下角显示消息通知框

    返回类型描述
    Promise如果设置了按钮,返回用户点击了哪个按钮
        hx.window.showInformationMessage('详情可访问<a href="http://www.dcloud.io">参考文档</a>');
    

    showWarningMessage

    在窗口右下角显示警告消息通知框

    返回类型描述
    Promise如果设置了按钮,返回用户点击了哪个按钮
        let resultPromise = hx.window.showWarningMessage('是否删除该文件?',['是','否']);
        resultPromise.then((result)=>{
            if(result == '是'){
                console.log("选择了是");
            }else if(result === '否'){
                console.log("选择了否");
    

    showQuickPick

    在窗口中间弹出一个可搜索的建议选择列表

    ], {placeHolder: '请选择一个目录或者文件'}); pickResult.then(function(result) { if (!result) { return; let backPath = result.backPath; //do something with result

    getActiveTextEditor

    获取当前激活的编辑器,如果没有打开的编辑器返回undefined

        let activeEditor = hx.window.getActiveTextEditor();
        activeEditor.then(function(editor){
            console.log(editor.document.fileName);
    

    showInputBox

    在窗口中间居中弹出一个输入框,获取用户输入。类似于浏览器的prompt方法。

    返回类型描述
    OutputChannel控制台通道
        let outputChannel = hx.window.createOutputChannel("foo");
        outputChannel.show();
        outputChannel.appendLine("Hello World");
    

    createTreeView

    从HBuilderX 2.7.12及以上版本开始支持
    

    创建指定viewId的视图,在窗体左侧区域创建一个和项目管理器同级的tab项。tab的内容区为一个树控件,可自行装载节点。

    viewId需要在package.json文件内的配置扩展点views中声明,完整的扩展视图流程参考如何注册一个新的视图?

    参数名称参数类型描述
    viewIdString视图Id,需要首先在配置扩展点views中声明。
    optionsTreeViewOptions创建TreeView时需要的设置项。
        class DemoTreeDataProvider extends hx.TreeDataProvider{
            constructor(demoData) {
                super();
                this._demoData = demoData;
            getChildren(element) {
                let demoData = this._demoData;
                return new Promise(resolve => {
                    if (!element) {
                        resolve(demoData);
                    } else {
                        resolve(element.children);
            getTreeItem(element) {
                return {
                    label:element.name,
                    collapsibleState:element.children ? 1 : 0,
                    command:{
                        command:element.children ? "":"extension.helloWorld",
                        arguments:[
                            element.name
        let demoData = [
                name:"Root1",
                children:[
                        name:"child1"
                        name:"child2"
                name:"Root2",
                children:[
                        name:"child3",
                        name:"child4"
        hx.commands.registerCommand("extension.helloWorld",function(param){
            hx.window.showInformationMessage("选中了TreeItem:" + param[0]);
        hx.window.createTreeView("extensions.treedemo",{
            showCollapseAll:true,
            treeDataProvider:new DemoTreeDataProvider(demoData);
    

    createWebView

    从HBuilderX 2.8.1及以上版本开始支持
    

    创建指定viewId的WebView控件视图,在窗体左侧或右侧区域创建一个tab项。tab内容为webview,webview里可装载html页面,可以较灵活的渲染自定义的内容。

    viewId需要在package.json文件内的配置扩展点views中声明

    返回类型描述
    WebViewPanelWebViewPanelWebViewPanel属性
        let webviewPanel = hx.window.createWebView("viewId",{
            enableScritps:true
        let webview = webviewPanel.WebView;
        webview.html = `
            <script>
                //    以下两种写法等同
                hbuilderx.onDidReceiveMessage((msg)=>{
                window.addEventListener("message",(msg)=>{
                hbuiderx.postMessage({
                    command: 'alert',
                    text: 'HelloWorld'
            </script>
            <img src="xxxx">
        webview.postMessage({
            command:"test"
        webview.onDidReceiveMessage((msg)=>{
            if(msg.command == 'alert'){
                hx.window.showInformationMessage(msg.text);
    

    registerUriHandler

    从HBuilderX 2.8.1及以上版本开始支持
    

    注册一个依赖hbuilderx协议的自定义网络请求处理器(schema),格式为:

    hbuilderx://requestExtension/exampleid/examplerequest/example?example1=example2&...
    \________/  \_____________/ \________/ \__________________________________________/
        |              |             |                  |
       协议     自定义插件请求的标记  插件id          任意的自定义信息
    

    当在浏览器地址栏中输入以上格式的url时或者跳转到以上格式的url,已安装了HBuilderX的系统将会把该请求转入HBuilderX, 由HBuilderX识别该请求并检测对应插件(如上例子中名为exampleid的插件)的配置信息(package.json)中是否声明了 onUri, 此时如果当前的插件并没有激活,那么HBuilderX会先激活该插件并把对应请求转发到由registerUriHandler方法注册的处理器中。

    如果exampleid对应插件并未安装,则HBuilderX会弹框提示是否安装该插件。

    适用的场景
  • 需要通过浏览器等外部应用启动HBuilderX,然后通过指定插件响应请求
  • 参数名称参数类型描述
    handlerUriHandlerscheme的处理器
    contextExtensionContext插件激活方法activate中传入的(context)参数对象
    返回类型描述
    Disposable注册的UriHandler的销毁器,可将该对象放置到插件的context.subscriptions数组内,插件卸载时,将会自动注销该handler
        hx.window.registerUriHanlder({
            handleUri:function(uri){
                //处理scheme请求
                let path = uri.path;
                let params = uri.query;
                hx.window.showInformationMessage(uri.toString());
        }, context);
    

    上面的示例中,假设插件id为foo,则在浏览器地址栏中输入hbuilderx://requestExtension/foo?param=abc时,将自动激活该插件,并执行handleUri函数,uri的值即为地址栏中输入的地址,示例中uri.query的值为param=abc。

    workspace

    workspace二级模块对象,用于处理和工作空间以及文档事件有关的逻辑

    getWorkspaceFolders

    从HBuilderX 2.7.12及以上版本开始支持
    

    获取项目管理器下所有的项目对象(不包含已关闭项目)

    返回类型描述
    Promise<Array>项目管理器下所有的项目
        var wsPromise = hx.workspace.getWorkspaceFolders();
        wsPromise.then(function(wsFolders) {
            console.log("项目管理器包含的项目数量:",wsFolders.length);
    

    getWorkspaceFolder

    从HBuilderX 2.7.12及以上版本开始支持
    

    获取某个文件所在的项目

        var wsPromise = hx.workspace.getWorkspaceFolder("%fsPath%");
        wsPromise.then(function(wsFolder) {
            console.log("文件所在项目:",wsFolder.name);
    

    openTextDocument

    通过指定的uri打开一个文档文件

    返回类型描述
    Promise返回打开的文档
        var documentPromise = hx.workspace.openTextDocument("foo/bar.js");
        documentPromise.then(function(document) {
            console.log("打开了文档:",document.fileName);
    

    onDidChangeConfiguration

    从HBuilderX 2.7.10及以上版本开始支持
    

    全局配置改变事件,比如”editor.fontSize”改变,或者通过插件扩展的配置项改变。

    返回类型描述
    Disposable该事件回调的销毁器,可将该对象放置到插件的context.subscriptions数组内,插件卸载时,将会自动注销该事件回调
        let configurationChangeDisplose = hx.workspace.onDidChangeConfiguration(function(event){
            if(event.affectsConfiguration("editor.fontSize")){
                console.log("修改了字体大小");
    

    onDidChangeWorkspaceFolders

    从HBuilderX 2.7.10及以上版本开始支持
    

    项目管理器内的项目新增或者移除时产生的事件

    返回类型描述
    Disposable该事件回调的销毁器,可将该对象放置到插件的context.subscriptions数组内,插件卸载时,将会自动注销该事件回调
        let wsFoldersChangeDisplose = hx.workspace.onDidChangeWorkspaceFolders(function(event){
            if(event.added){
                event.added.forEach(item=>console.log("新增了项目:",item.name));
            if(event.removed){
                event.removed.forEach(item=>console.log("移除了项目:",item.name));
    

    onWillSaveTextDocument

    文档即将要保存的事件,注意该事件是同步调用,会阻塞用户界面,为了避免长时间阻塞界面,目前设置了超时机制,超时时间为2s。

    注意你在该事件回调中执行的逻辑不应该占用太长的时间,如果超时将会出现一些不可预测的问题。

    返回类型描述
    Disposable该事件回调的销毁器,可将该对象放置到插件的context.subscriptions数组内,插件卸载时,将会自动注销该事件回调
        let onDidChangeTextDocumentEventDispose = hx.workspace.onDidChangeTextDocument(function(event){
            let document = event.document;
            //do something with document.
    

    onDidChangeTextDocument

    文档被修改时的事件

    返回类型描述
    Disposable该事件回调的销毁器,可将该对象放置到插件的context.subscriptions数组内,插件卸载时,将会自动注销该事件回调
        let onDidChangeTextDocumentEventDispose = hx.workspace.onDidChangeTextDocument(function(event){
            let document = event.document;
            //do something with document.
    

    onDidSaveTextDocument

    文档被保存时的事件

    返回类型描述
    Disposable该事件回调的销毁器,可将该对象放置到插件的context.subscriptions数组内,插件卸载时,将会自动注销该事件回调
        let onDidSaveTextDocumentEventDispose = hx.workspace.onDidSaveTextDocument(function(document){
            //do something with document.
    

    onDidOpenTextDocument

    从HBuilderX 2.7.6及以上版本开始支持
    

    文档打开时的事件

    返回类型描述
    Disposable该事件回调的销毁器,可将该对象放置到插件的context.subscriptions数组内,插件卸载时,将会自动注销该事件回调
        let onDidOpenTextDocumentEventDispose = hx.workspace.onDidOpenTextDocument(function(document){
            //do something with document.
        context.subscriptions.push(onDidOpenTextDocumentEventDispose);
    

    applyEdit

    根据指定的WorkspaceEdit对象编辑文档。WorkspaceEdit对象内要设定被修改文档的uri和要执行修改的TextEdit操作对象。

        let editorPromise = hx.window.getActiveTextEditor();
        editorPromise.then((editor)=>{
            let workspaceEdit = new hx.WorkspaceEdit();
            let edits = [];
            edits.push(new hx.TextEdit({
                start: 0,
                end: 0
            }, "foo"));
            workspaceEdit.set(editor.document.uri,edits);
            hx.workspace.applyEdit(workspaceEdit);
    

    getConfiguration

    根据指定的section获取对应的配置

        let config = hx.workspace.getConfiguration()
        let fontSize = config.get("editor.fontSize");
        //或者也可以这样
        let config = hx.workspace.getConfiguration("editor")
        let fontSize = config.get("fontSize");
    
    从HBuilderX 2.7.6及以上版本开始支持
    

    env二级模块对象,包含运行环境信息和系统交互相关的方法

    属性名属性类型描述
    appNameString应用程序名称:HBuilder X
    appVersionString应用程序主版本号,可在菜单【帮助】-【关于】中查看
    appRootString应用程序安装路径
    appDataString应用程序数据存放路径
    clipboardClipboard剪切板对象,可用于读取剪切板内容和写入内容到剪切板,目前仅支持文本格式

    openExternal

    打开一个外部链接,比如https://www.dcloud.iomailto:ide@dcloud.io

    返回类型描述
    Promise返回是否打开成功
        var openPromise = hx.env.openExternal("https://www.dcloud.io");
        openPromise.then(function(success) {
            console.log("打开链接结果:",success);
    

    Clipboard

    从HBuilderX 2.7.6及以上版本开始支持
    

    剪切板对象,可用于读取剪切板内容和写入内容到剪切板,目前仅支持文本格式

    readText

    读取剪切板内容

        var readPromise = hx.env.clipboard.readText();
        readPromise.then(function(text) {
            console.log("读取剪切板内容:",text);
    

    writeText

    写入剪切板内容

    返回类型描述
    Booleantrue表示配置项被修改,false表示配置项没有被修改
        let configurationChangeDisplose = hx.workspace.onDidChangeConfiguration(function(event){
            if(event.affectsConfiguration("editor.fontSize")){
                console.log("修改了字体大小");
    

    WorkspaceFoldersChangeEvent

    项目管理器中新增或者移除项目时产生的事件类型

    属性名属性类型描述
    addedArray新增的项目列表
    removedArray移除的项目列表
        let wsFoldersChangeDisplose = hx.workspace.onDidChangeWorkspaceFolders(function(event){
            if(event.added){
                event.added.forEach(item=>console.log("新增了项目:",item.name));
            if(event.removed){
                event.removed.forEach(item=>console.log("移除了项目:",item.name));
    

    TextDocumentWillSaveEvent

    文档即将保存的事件

    属性名属性类型描述
    documentTextDocument该编辑器关联的文档
    selectionTextSelection当前光标选中的位置
    selectionsArray当前多光标选中的位置集合
    optionsTextEditorOptions该编辑器的设置项

    修改当前编辑器打开的文档

        let editorPromise = hx.window.getActiveTextEditor();
        editorPromise.then(function(editor) {
            let selection = editor.selection;
            let document = editor.document;
            let word = document.getText(selection);
            let reversed = word.split('').reverse().join('');
            editor.edit(editBuilder => {
                editBuilder.replace(selection, reversed);
    

    setSelection

    设置主选择区域,该API会首先清除原来的光标选择,如果要使用多光标,请使用addSelection方法

    let editor = hx.window.getActiveTextEditor();
    editor.then((editor)=>{
        editor.setSelection(10,12);
    

    addSelection

    增加新的选择区域,调用后会在编辑器内追加一个新一个光标。

    let editorPromise = hx.window.getActiveTextEditor();
    editorPromise.then((editor)=>{
        editor.setSelection(10,12).then(()=>{
            editor.addSelection(16,18);
    

    TextDocument

    编辑器打开的文档文件

    属性名属性类型描述
    fileNameString文件名称
    isDirtyBoolean是否是修改状态
    isUntitledBoolean是否是无标题文件
    lineCountNumber文档总行数
    uriUri文档的uri,如果是本地文件,可通过uri.fsPath获取本地文件路径
    languageIdString编程语言Id,如’javascript’,’html’等,完整id列表参见下面
    workspaceFolderWorkspaceFolder该文档文件所属的项目对象

    getText

    获取指定区域内的文本

    属性名属性类型描述
    startNumber起始位置
    endNumber结束位置

    OutputChannel

    输出通道,在添加内容到控制台时,会将通道名称作为前缀输出,eg:[${channel}] 这是要输出的内容。

        let outputChannel = hx.window.createOutputChannel("foo");
        outputChannel.show();
        outputChannel.appendLine("Hello World");
    
        let outputChannel = hx.window.createOutputChannel("foo");
        outputChannel.show();
        outputChannel.appendLine("Hello World");
    

    Configuration

        let eslintConfig = hx.workspace.getConfiguration("eslint-js")
        let validateOnDocumentChanged = eslintConfig.get("validateOnDocumentChanged",false);
    

    update

    返回类型描述
    PromisePromise
        let eslintConfig = hx.workspace.getConfiguration("eslint-js")
        eslintConfig.update("validateOnDocumentChanged",true).then(()=>{
            console.log("更新配置成功。");
    

    DiagnosticCollection

    返回类型描述
    PromisePromise
        let diagnositics = hx.languages.createDiagnosticCollection('eslint');
        diagnositics.set("foo.js",[
                column: 0,
                line: 0,
                message: 'a error message.'
    

    DiagnosticItem

    属性名属性类型描述
    lineString在文档第几行
    columnString在文档第几列
    messageString问题详细信息
    severityString问题级别,取值范围:’error’,’warn’. 默认值是’error’

    WorkspaceEdit

    工作空间的一组编辑操作

        let workspaceEdit = new hx.WorkspaceEdit();
        let edits = [];
        edits.push(new hx.TextEdit({
            start: 0,
            end: 0
        }, "foo"));
        workspaceEdit.set(doc.uri, edits);
        hx.workspace.applyEdit(workspaceEdit);
    

    TextEdit

    属性名属性类型描述
    uriString或Uri项目目录地址
    nameString项目目录名称
    natureString项目类型
    idString项目唯一id

    InputBoxOptions

    输入框设置

    属性名属性类型描述
    promptString输入框的描述
    valueString输入框的默认值
    placeHolderString输入框内容为空时的占位内容
    passwordBoolean是否是密码框

    QuickPickOptions

    快速选择框设置

    属性名属性类型描述
    labelString候选项名称
    descriptionString候选项描述

    如果要传递额外的数据,可以追加自定义的属性,当用户选择该项后,会通过回调返回选择了哪个候选项

    TreeViewOptions

    创建TreeView需要的配置项

    属性名属性类型描述
    showCollapseAllBoolean是否显示折叠所有
    treeDataProviderTreeDataProviderTreeView树控件获取数据的接口,需要自己写一个子类实现该接口。
  • WebViewOptions

    WebViewOptions

    从HBuilderX 2.8.1及以上版本开始支持
    

    调用createWebView创建WebView时需要的配置项

    参数名称参数类型描述
    webViewWebViewWebView 关联的WebView对象
    dispose()dispose方法调用关闭该扩展视图

    WebView

    从HBuilderX 2.8.1及以上版本开始支持
    

    调用createWebView创建WebView对象

    参数名称参数类型描述
    optionsWebViewOptions调用createWebView创建WebView时传入的options参数
    htmlStringWebView中要显示的html内容

    onDidReceiveMessage

    收到hbuilderx.postMessage发出的消息时调用回调函数。

       webview.onDidReceiveMessage((message)=>{ console.log(message) });
    

    postMessage(message: any): Thenable

    在WebView中发送消息

    返回类型描述
    ThenableJavascript异步延迟后执行

    TreeDataProvider

    TreeView树控件获取数据的接口,不可直接实例化该对象,需要自己写一个子类实现该接口,每个自定义的treeDataProvider都需要实现该接口下列出的方法

    getChildren

    获取某个节点的下的子节点,如果参数为空,则表示要获取根节点

    返回类型描述
    Promise<Any[]>Promise

    getTreeItem

    获取用于显示自定义数据element(通过getChildren获取的对象)的TreeItem对象

    属性名属性类型描述
    collapsibleStateNumber是否可展开,目前取值有:0:不可展开;1:可展开
    labelString该item的显示名称
    contextValueString该item的上下文信息,在通过menus扩展点的view/item/context类别注册右键菜单时,用when表达式中的viewItem变量控制菜单显示。举例:viewItem == 'test'
    commandCommandInfo当选中该item时要执行的命令
    tooltipString鼠标悬浮到该item上的tooltip提示消息

    CommandInfo

    配置一个命令需要的信息对象

    属性名属性类型描述
    commandString要执行的命令id
    argumentsany[]执行该命令时传递的参数

    Disposable

    资源释放接口,HBuilderX开放的部分API返回了该对象,将该对象添加到插件激活时的参数context.subscriptions数组内,插件卸载时将自动释放对应的资源。

    dispose

    UriHandler

    uri处理器接口

    handleUri

    参数名称参数类型描述
    uriUrischeme请求对应的uri,eg:hbuilderx://requestExtension/extensionId?foo=bar

    统一资源访问符

    属性名属性类型描述
    fsPathString本地文件地址
    authorityStringUri中的authority
    fragmentStringUri中的fragment
    pathStringUri中的path
    queryStringUri中的query
    schemeStringUri中的scheme

    扩展点是通过在插件package.json文件中contributes节点下定义的一些JSON格式的配置项。以下是目前HBuilderX支持的扩展点列表:

    configuration

    configuration扩展点,会将扩展的配置项注册到HBuilderX的全局可视化配置里设置-插件配置

    title

    每个插件扩展的配置是分配到同一组下的,title指的是该组的名称,一般写的是插件名称。

    properties

    properties内配置的是一个jsonobject对象,该对象的key代表着要扩展的配置项id,value是一个符合JSON Schema规范的jsonobject,目前支持的字段包括:

  • type 类型。支持的类型包括:string、boolean、number。
  • description 描述
  • default 默认值
  • enum 可选值,目前只有type为string或number时可用
  •     "contributes": {
            "configuration":{
                "title":"eslint-js",
                "properties":{
                    "eslint-js.autoFixOnSave":{
                        "type":"boolean",
                        "default":true,
                        "description":"保存时自动修复"
                    "eslint-js.validateOnDocumentChanged":{
                        "type":"boolean",
                        "default":false,
                        "description":"启用实时校验"
    

    commands

    commands扩展点用于声明一个命令命令可以通过menus扩展点和菜单关联到一起

    注意:当一个命令将要执行时,将会触发一个onCommand:${commandId}activationEvent用于激活监听该命令的插件

        "contributes": {
            "commands": [
                "command": "extension.firstExtension",
                "title": "Hello World"
    

    snippets

    snippets扩展点可以扩展指定编程语言的代码块,可扩展的编程语言Id列表见这里。扩展示例代码如下:

     "contributes": {
            "snippets": [
                "language": "css",
                "path": "./snippets/css.json"
                "project":"uni-app",
                "language": "css",
                "path": "./snippets/condition_comment.json"
    
    属性名称属性类型是否必须描述
    projectString是否只在指定的项目类型下生效,目前的可取值为”Web”,”App”,”Wap2App”,”uni-app”;如果要支持多项目类型可以通过逗号分隔,例如:”Web,uni-app,App”
    languageString编程语言ID,用于限定只在指定的语言下生效,语言Id的列表参见这里
    pathString要扩展的代码块列表文件路径,文件内容格式见下面

    代码块格式

    每个配置项的说明如下表:

    名称描述
    key代码块显示名称,显示在代码助手列表中的名字,以下例子中”console.log”就是一个key。
    prefix代码块的触发字符,就是敲什么字母匹配这个代码块。
    body代码块的内容。内容中有如下特殊格式: 1表示代码块输入后光标的所在位置。如需要多光标,就在多个地方配置1 表示代码块输入后光标的所在位置。如需要多光标,就在多个地方配置1,如该位置有预置数据,则写法是1:foo1,多选项即下拉候选列表使用{1:foo1},多选项即下拉候选列表使用
    triggerAssist为true表示该代码块输入到文档后立即在第一个tabstop上触发代码提示,拉出代码助手,默认为false。

    代码块示例

    // ./snippets/javascript.json
        "console.log": {
            "prefix": "logtwo",
            "body": [
                "console.log('$1');",
                "\tconsole.log('${2:foo/bar}');"
            "triggerAssist": false,
            "description": "Log output to console twice"
    

    插件激活是通过package.json文件中的activationEvents字段控制的。当activationEvents配置的事件发生时将会激活插件。如果activationEvents为空,则HBuilderX启动时将会自动激活该插件。

    我们强烈建议你一定要配置activationEvents,启动时就激活插件将会降低HBuilderX的启动性能。

    以下列出目前可用的激活事件:

  • onCommand
  • onView
  • workspaceContains
  • onUri
  • onCommand

    该激活事件将在某个插件命令即将要触发时产生。

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

    onView

    该激活事件将在某个扩展视图(view)即将打开显示的时候触发,通常是通过菜单【视图】-【显示扩展视图】选择某个扩展视图时触发。

    "activationEvents": [    "onView:extension.demoview"]
    

    workspaceContains

    当某个项目下包含指定文件时会触发该激活事件,文件的路径是相对于项目的相对路径。

    注意:该类事件目前只在HBuilderX启动时触发,HBuilderX启动后再新建对应的文件不会触发此类事件。

    "activationEvents": [
        //当项目管理器下的某个项目下存在.ftp/ftp.json文件时会触发该事件。
        "workspaceContains:.ftp/ftp.json"
    

    onUri

    声明可以响应scheme协议请求,当某个scheme指定要请求某个插件时,如果插件声明后onUri事件,则会自动激活该插件,否则不会激活。

    "activationEvents": [
        //声明可以响应scheme协议请求
        "onUri"
    

    事件*代表该插件将在HBuilderX启动时就立即激活,作用和不配置activationEvents一样。

    最佳实践是只监听需要监听的事件,尽量让插件懒加载

    插件目录名称

    插件的目录名称就是插件的唯一ID,不能和其他插件冲突,名称只能用英文单词,不支持用空格分割。

    package.json

    所有的插件在根目录都要有一个package.json文件,该文件继承npm规范,并扩展了部分字段,以下列出各个字段的含义:

    字段名称类型是否必须描述
    nameString插件名称
    displayNameString用于展示在插件列表中的名称
    versionString插件版本号,检查升级时会用到
    enginesObject该Object的属性至少要包含HBuilderX,属性值为兼容的主版本号,如果HBuilderX的版本低于该版本,将会提示用户升级HBuilderX。例如:{“HBuilderX”:”^2.7.0”}。
    descriptionString简短的插件描述,不要超过30个字
    mainString插件代码入口文件,配置型插件可不填
    activationEventsArray激活事件的列表,如为空,则表示该插件不会懒加载
    contributesObject插件的配置扩展点
    extensionDependenciesArray该插件依赖的其他插件id
    "name": "helloworld", "displayName":"简单的插件示例", "description": "简单的插件示例,用于测试插件API", "version": "1.0.0", "publisher": "coder", "engines": { "HBuilderX": "^2.7.0" "categories": [ "Other" "main": "./extension", "activationEvents": [ "onCommand:extension.helloWorld", "onView:extensions.treedemo" "contributes": {}, "extensionDependencies": [ "foo1","bar1" "dependencies": {} HuskyYellow FE @ 光合新知(北京)科技有限公司 49.9k
  • 粉丝