前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >基于区块开发(三):VSCode插件

基于区块开发(三):VSCode插件

作者头像
Dickensl
发布于 2022-06-14 05:53:06
发布于 2022-06-14 05:53:06
61800
代码可运行
举报
文章被收录于专栏:睿Talks睿Talks
运行总次数:0
代码可运行

一、前言

上一篇文章 中,我介绍了服务于区块开发的命令行工具是如何实现的,本文将沿着区块开发这一主题继续讲解 VSCode 插件的实现方式。

本系列总共 3 篇文章,以下是传送门:

基于区块开发(一):概述

基于区块开发(二):命令行工具

基于区块开发(三):VSCode插件

二、区块列表展示

如果刚接触 VSCode 插件开发,可以先看看我之前写的 VS Code插件开发介绍

为了方便用户使用,我希望有一个专门的 tab 页分类列出所有的区块,先看一下效果:

要在左侧工具栏添加 tab,需要先在 package.json 文件中配置一个 View Container 和一个 View

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"contributes": {
  "viewsContainers": {
    "activitybar": [
      {
        "id": "tce-block",
        "title": "TCE Block",
        "icon": "media/block.svg"
      }
    ]
  },
  "views": {
    "tce-block": [
      {
        "id": "tceBlock",
        "name": "TCE Block",
        "icon": "media/dep.svg",
        "contextualTitle": "TCE Block"
      }
    ]
  }
}

这里指定了 tab 的位置放在左侧工具栏 activitybar,另一个可选项是 panel,在编辑器底部(终端)的位置。然后再给刚添加的这个 View Container 指定一个 View,通过 tce-block 这个 ID 进行关联。

下一步就是定制 View 的显示内容了。由于显示的内容就是一棵目录树,所以用到了 VSCode 插件开发中内置的 Tree View API。下面我们来定义一棵树,关键是实现 vscode.TreeDataProvider 这一接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class BlockProvider implements vscode.TreeDataProvider<Block> {
  constructor(private workspaceRoot: string) {}

  getTreeItem(element: Block): vscode.TreeItem {
    return element;
  }

  async getChildren(element?: Block) {
    if (!this.workspaceRoot) {
      return [];
    }

    // 不是根目录,返回元素的children
    if (element) {
      if (element.children.length > 0) {
        return element.children;
      }
      return null;
    }
    // 根目录,构造树形数据结构
    else {
      const resp = await fetchData<BlockCategories>(
        'http://xxx.com/block-categories.json'
      );

      if (!resp) {
        vscode.window.showErrorMessage('获取区块列表失败');
        return [];
      }

      const { blocks } = resp;
      return toBlock(blocks);
    }
  }
}

这里的重点是实现 getChildren 方法,返回树的数据结构。这里有 2 种情况:

  • 参数 element 为空时,说明是根目录,需要构造出树的第一层数据结构(数组)。
  • 参数 element 非空时,返回子节点数组。

toBlock 函数的作用是构造出树的所有节点。我设计的树只有 2 层,第一层是区块分类,第二层是区块实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function toBlock(categories: BlockItem[]): Block[] {
  // 区块分类
  return categories.map((category) => {
    const { id, label, children } = category;
    const categoryItem = new Block(
      id,
      label,
      '',
      vscode.TreeItemCollapsibleState.Collapsed
    );
    
    // 区块实例
    categoryItem.children = children!.map((blockItem) => {
      const { id: blockId, label: blockLabel, url } = blockItem;
      const block = new Block(blockId, blockLabel, url!);
      block.type = blockItem.type;
      return block;
    });

    return categoryItem;
  });
}

下面再来看树节点的定义,继承自 vscode.TreeItem

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export class Block extends vscode.TreeItem {
  children: Block[] = [];
  type: number = 2;

  constructor(
    public readonly id: string,
    public readonly label: string,
    public readonly url: string,
    public readonly collapsibleState?: vscode.TreeItemCollapsibleState
  ) {
    super(label, collapsibleState);

    this.id = id;
    this.tooltip = `${this.label}区块`;

    // 区块实例
    if (url) {
      this.contextValue = 'block'; // 控制操作按钮的显示隐藏
      this.command = {
        title: this.label, // 标题
        command: 'tceBlock.openWebview', // 命令 ID
        tooltip: this.label, // 鼠标覆盖时的小小提示框
        arguments: [this], // 向 registerCommand 传递的参数。
      };
    }
  }
}

Block 的定义是包含所有类型的节点的(区块分类和区块实例),所以需要根据构造函数传入的值来定义不同的行为,比如这里对于区块实例,会有 url 属性,点击他会打开一个 webview,这块在下一节详细讲解。

到此为止,树形结构已经能正常展示了。

三、预览区块

区块的预览本质上来说就是在 vscode 里面打开一个网页,这里就用到了 Webviews API。核心代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let currentPanel: vscode.WebviewPanel | undefined = undefined;

export function openWebView(url: string) {
  if (currentPanel) {
    currentPanel.dispose();
  }

  currentPanel = vscode.window.createWebviewPanel(
    'tceBlock',
    'TCE Block',
    vscode.ViewColumn.One,
    {
      retainContextWhenHidden: true, // 控制是否保持webview面板的内容(iframe),即使面板不再可见。
      enableScripts: true, // 下面的 html 页可以使用 Scripts
    }
  );
  currentPanel.webview.html = getWebviewContent(url);

  // Reset when the current panel is closed
  currentPanel.onDidDispose(() => {
    currentPanel = undefined;
  }, null);
}

function getWebviewContent(url: string) {
  return `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cat Coding</title>
    <style>
      html,
      body {
          margin: 0 !important;
          padding: 0 !important;
          width: 100%;
          height: 100%;
      }
      #blockFrame {
          width: 100%;
          height: 100%;
      }
  </style>
</head>
<body>
<iframe id='blockFrame' src="${url}" scrolling="auto"></iframe>
</body>
</html>`;
}

代码很好理解,分为以下几步:

  • 新建一个 webviewPanel
  • 设置 webviewPanelhtml
  • html 中嵌入一个 iframe 来动态加载网页

这个操作会注册成 vscode 的一个命令,然后在点击区块实例的时候被调用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vscode.commands.registerCommand('tceBlock.openWebview', (node: Block) => {
  openWebView(node.url);
});

export class Block extends vscode.TreeItem {
  constructor(...) {
    ...
    // 区块实例
    if (url) {
      ...
      this.command = {
        command: 'tceBlock.openWebview', // 执行上面定义的命令
        arguments: [this], // 向 registerCommand 传递的参数
        ...
      };
    }
  }
}

四、安装区块

通过区块列表安装

我们希望插入区块这个操作显示在区块实例的边上,当鼠标移动到对应区块时被激活:

这就需要在 package.json 文件中定义这个操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"contributes": {
  "menus": {
    "view/item/context": [
      {
        "command": "tceBlock.addBlock",
        "when": "view == tceBlock && viewItem == block",
        "group": "inline"
      }
    ]
  }
}

具体的区块插入代码跟 上一篇文章 大同小异,在此就不重复了。这里会用到一些 VSCode 的 API,如通过对话框的方式获取用户希望区块插入的位置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const options: vscode.OpenDialogOptions = {
  title: '请选择区块插入位置',
  openLabel: '插入区块',
  canSelectMany: false,
  canSelectFiles: false,
  canSelectFolders: true,
};

const fileUri = await vscode.window.showOpenDialog(options);

insertPath = fileUri[0].fsPath;
通过上下文菜单安装

为了省却选择区块安装目录的麻烦,还能直接在项目中通过上下文菜单的方式安装区块:

这需要在 package.json 中配置上下文菜单:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"contributes": {
  "menus": {
    "explorer/context": [
      {
        "command": "tceBlock.generateBlock",
        "group": "1_modification"
      }
    ]
  }
}

选择插入区块后会提升选择区块实例:

这里用到了 VSCode 的另一个 API:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const blockNames: any[] = []
...
const blockItem = await vscode.window.showQuickPick(blockNames, {
  placeHolder: '请选择要插入的区块',
});

五、总结

本文讲解了基于区块开发的 VSCode 插件的实现细节,主要功能是以树的形式展示区块列表、预览区块和安装区块。当中用到的 VSCode API 非常实用,可以用于开发读者自己设计的插件。

本文是本系列文章的终章,希望对你有所帮助,后会有期。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
vscode插件开发入门
在我们日常使用中,会安装很多插件,如: 主题、Prettier、code snippets、Eslint、Jest Runner、Git等等。每种插件都能解决我们实际开发中的某一块诉求。我把所有的插件大致归为三类:UX/UI类、语言类、工具类
gary12138
2022/10/05
5.7K0
vscode插件开发入门
写一个VSCode扩展
自从使用过 VSCode 后就再也离不开 VSCode,其轻量的代码编辑器与诸多插件让多数开发者爱不释手。同样我也不例外,一年前的我甚至还特意买本《Visual Studio Code 权威指南》的书籍,来更进一步了解与使用。
愧怍
2022/12/27
2.8K0
写一个VSCode扩展
VS Code插件开发介绍(一)
前段时间做了一个基于命令行的效率工具,可以自动生成组件的模板代码。自己用起来还觉得挺好,但在组内案例几次后大家都不愿意用,究其原因还是命令行工具使用起来门槛有点高,不方便。由于组内已经统一使用VS Code进行开发了,于是决定研究下VS Code的插件开发,让效率工具更方便的用起来。
Dickensl
2022/06/14
7690
VS Code插件开发介绍(一)
Vue3+NodeJS 接入文心一言, 发布一个 VSCode 大模型问答插件
随着大模型能力越来越卷,在垂直领域的落地也在加快,对于大模型代码生成能力而言,最简洁高效的方式就是集成为常用IDE的插件,在vscode的插件战场中,比较知名的就有 GitHub Copilot, 智谱清言的codegeex, 讯飞星火的iFlyCode。
五月君
2023/11/14
2.3K0
Vue3+NodeJS 接入文心一言, 发布一个 VSCode 大模型问答插件
【Web技术】746- VSCode 插件开发入门教程
之前一直以为开发VS code插件是一件很难的事情,后来工作上需要搞一个效率小工具,就试着找了些资料来入门,发现其实就入门和开发一些简单功能的插件来说难度还是很低的。因为vscode本身是基于electron开发的,所以总体来说开发插件就是在写node代码,额外再加一些编辑器api,插件发布的过程和npm包的发布很类似。
pingan8787
2020/10/23
2.3K0
【Web技术】746- VSCode 插件开发入门教程
从小白到大白 — 如何开发 VSCode 插件
由于之前的国际化的项目中总是要统计老项目中待翻译的内容,然后再交由业务进行翻译,如果总是人为统计不仅相当耗费精力和时间,而且还不能保证是否有遗漏,因此想通过编写一个 i18n-helper 插件来实现这个功能。
winty
2023/11/12
1.6K0
从小白到大白 — 如何开发 VSCode 插件
编写你的第一款VSCode插件
工欲善其事,必先利其器。对于一名程序猿来说,好的编辑器能够大大提高写代码的效率。VSCode作为微软主推的开源跨平台编辑器,是前端开发的利器,它拥有各种丰富的插件,更是使得其如虎添翼。
腾讯IVWEB团队
2020/06/24
2.6K0
三种插件开发模式,带你玩废tinymce
前言 TinyMCE是一款开源、易用、UI时新、所见即所得的富文本编辑器。是富文本领域中的佼佼者。整体设计和模式,都是非常不错的。其提供的API 极其丰富和强大,简单点 就是专业牛👍,可供广大开发者用户,方便快捷的自行进行扩展或根据实际业务需求进行二次开发。下面我将分享3种方式,带你玩废 tinymce,适合接触过 tinymce 的 小伙伴,如果没有接触过 就随便看看,收藏也不吃亏,保不齐,后面用得上,知道可以这样玩就好了😎 利用tinymce官方提供的 UI 组件扩展 tinymce 官方提供还算多的
Fivecc
2022/11/21
5.1K1
三种插件开发模式,带你玩废tinymce
从零开发一款基于 webview 的 vscode 扩展
在团队降本提效的基建中,洛竹开发了一款 vscode 插件,第一版我使用的是 vscode 内置 UI,虽说也能用,但是用户体验欠佳。由于 vscode 内置 UI 不够灵活,一番调研后我决定使用 webview 重构。
用户1250838
2021/09/18
4.9K0
从零开发一款基于 webview 的 vscode 扩展
VSCode变量命名转换插件(Var-Conv)
有一个良好的变量命名方式对于一个程序员是相当的重要的,但是入门的编程语言不同或者各自的习惯不同导致实际工作中的变量命名依然是层次不齐的,在不同的平台间,服务间的变量命名更是什么样的都有,为了应对不同的变量命令我一开始使用的是uTools中的插件,也推荐更多朋友使用,在IED中选中变量后alt+空格呼起uTools会自动匹配到变量替换的插件,但是最后升级后发现还需要搜索到插件后才能再转换,所以就想不脱离VSCode就可以直接转换变量的命名方式,通过一顿的搜索参考,终于把这个插件做了出来。
前端小鑫同学
2022/12/26
1.1K0
VSCode变量命名转换插件(Var-Conv)
一起来写 VS Code 插件:实现一个翻译插件
上一篇介绍了用 code snippets 的方式开发一个插件,本文将通过实现一个翻译插件实例的方式来熟悉 VS Code 插件开发的常见功能和方法。当然大家可以前往 VS Code 官网API 和官方 GitHub 示例 查看和学习。
狂奔滴小马
2021/11/22
1.4K0
一起来写 VS Code 插件:实现一个翻译插件
VSCode插件开发:LaTeX Snippets
请注意,本文编写于 442 天前,最后修改于 126 天前,其中某些信息可能已经过时。
gyro永不抽风
2021/05/21
3.1K0
造一轮子:vscode插件--支持json生成go struct,curl生成go代码
最近学习了一下如何写vscode插件,不得不感叹大神写的vscode框架就是厉害,简单通过配置文件加上事件处理代码就可以扩展编辑器前端的能力。膜拜之余,造了一个轮子,交互过程如下,右键json文件选择“json生成go结构体(JsonToGo)”就可以生成json文件对应的golang struct;选择“生成golang代码或者结构体->curl生成go代码(CurlToGo)”就可以从curl命令(从浏览器的debug tool直接copy过来)生成对应的golang客户端代码,简单修改即可发起http请求。
golangLeetcode
2023/03/01
1.3K0
造一轮子:vscode插件--支持json生成go struct,curl生成go代码
“改造” VS Code 编辑器,一起写个插件吧!
作为一个靠代码作为“生计”的开发者,bug 写的好不好,编辑器真的很重要!那么 Visual Studio Code 这个大名你肯定不会陌生。作为一个老厉害的编辑器,它的过人之处简单讲讲来说有这么几点:
HelloGitHub
2021/05/08
6640
“改造” VS Code 编辑器,一起写个插件吧!
一起来写 VS Code 插件:VS Code 版 CNode 已上线
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。本篇将通过实现 VS Code 版 CNode, 来带领大家一起熟悉 VSCode Webview 强大的功能。在开始之前,我们先参考 官网关于 webview 的介绍。Webview API 允许扩展在 visualstudio 代码中创建完全可定制的视图,可以将 webview 看作是 VS Code 中的 iframe。
狂奔滴小马
2021/11/24
1.4K0
一起来写 VS Code 插件:VS Code 版 CNode 已上线
写了一个 vscode 插件:自动添加可选链
选择 javascript,用 @babel/parser 解析,在后边可以看到 parse 出的 AST。
神说要有光zxg
2023/08/28
3500
写了一个 vscode 插件:自动添加可选链
DIY VSCode 插件,让你的开发效率突飞猛进
Visual Studio Code(简称 VSCode)凭借其占用内存小、文件加载快、稳定性好、插件丰富等等特点,从众多 IDE 中脱颖而出,受到了广大开发人员的青睐。工欲善其事,必先利其器。选择适合自己的 VSCode 插件,能够让你的开发效率突飞猛进。VSCode 插件市场 上面插件百花齐放,但实际开发过程中问题复杂且多变,有时候并不能找到完全满足你实际开发需求的插件,那就自己动手 DIY 一个吧。VSCode 提供以下扩展能力:代码自动补全、自定义命令/菜单/快捷键、悬浮提示、自定义跳转、主题定制、自定义 WebView 等等。你可以根据自己的需要随意组合使用。
政采云前端团队
2019/12/19
2K0
那些好用的 VS Code 插件,究竟是如何提高编码效率的?
在开始正题之前,我们先回忆一下自己在 VS Code 上常用并且获得编码幸福度的是不是包含以下几个点。
HelloGitHub
2021/06/24
1.6K0
那些好用的 VS Code 插件,究竟是如何提高编码效率的?
腾讯AlloyTeam团队给 VSCode 贡献400+行核心代码增强其插件化能力
作者:enoyao,腾讯工程师 在前几天腾讯文档 AlloyTeam 给 VSCode 合入了大概 400 行核心代码,主要涉及到 VSCode 配置化的部分,增强其插件化能力,提供更多的匹配接口,整理部分代码结构和补充功能单测。 由于腾讯文档最近在完善我们的配置化系统,在完善的过程也探索了多种实现方案,也分析了很多产品的实现方式,如大名鼎鼎的 VSCode,我们也希望把我们积累经验贡献给开源社区,一起共同进步。 其中代码的提交者为 AlloyTeam 的工程师 @Wscats ,而合入代码的是微软 V
腾讯技术工程官方号
2023/04/10
8900
腾讯AlloyTeam团队给 VSCode 贡献400+行核心代码增强其插件化能力
VS Code—插件的开发
说再多也不如做一遍,这里我们一起来一步步做一个插件。就做官网的那个demo,wordCounter,用于统计当前页单词量。 官网是TypeScript,我不会...这里就用nodejs来示例。
余生
2018/10/15
4.1K0
推荐阅读
相关推荐
vscode插件开发入门
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验