24
这里的序号承接上文

十一. hover的效果(官网例子模糊)

想象一下鼠标悬停在一个语句上就会浮现出你的提示信息, 是不是还挺酷的, 说干就干,但还是忍不住吐槽一下官网的例子太粗糙了.

hover就不用去定义命令了, 因为他的触发规则就是悬停

我们新建hover.js文件

const vscode = require('vscode');
const path = require('path');

module.exports = vscode.languages.registerHoverProvider('javascript', {
  provideHover(document, position, token) {
    const fileName    = document.fileName;
    const workDir     = path.dirname(fileName);
    const word        = document.getText(document.getWordRangeAtPosition(position));
    // console.log(1, document)
    // console.log(2, position)
    // console.log(3, token)
    console.log(4, '这个就是悬停的文字', word)
    // 支持markdown语法
    return new vscode.Hover(
    `### 我就是返回的信息!
      1. 第一项:
        - 第一个元素
        - 第二个元素
      2. 第二项:
        - 第一个元素
        - 第二个元素
  `);
  }
 }
);

index.js文件如下

const vscode = require('vscode');
const message = require('./message.js');
const navigation = require('./navigation.js');
const progress = require('./progress.js');
const hover = require('./hover.js');

 function activate(context) {
    vscode.window.showInformationMessage('插件成功激活!');
    context.subscriptions.push(message);
    context.subscriptions.push(navigation);
    context.subscriptions.push(progress);
    context.subscriptions.push(hover);
}

module.exports = {
    activate
}
  1. provideHover是不用引用的
  2. 支持markdown语法
  3. 因为悬停其他插件也有相关显示, 那么vscode会按顺序展示每个插件的hover效果

image.png

由此可见, 我们hover的时候可以获得被悬停的文字, 可以获得其所在的文件位置, 那么我们就可以去node_modules里面查找对应的文件了, 然后获取到他的版本号与更新时间和官网地址, 所以那些在 package.json中hover出现详情的插件的原理, 你!懂!了!吧!

我们完全可以利用这个快捷查找一些你们公司内部的词汇的具体含义, 或者某些code与id 代表的含义.

十二. 模板的定义, 打造属于自己团队的快捷开发

``文件中配置模板

    "contributes": {
        "snippets": [
            {
                "language": "javascript",
                "path": "./snippets/cc.json" // 这里就是存放模板的文件
                }
        ]
    },

./snippets/cc.json内容如下:

{
  "名字写在这里真奇怪, 使公司模板统一": {
      "prefix": "cc 左侧名字",
      "body": [
        "for (xxxxxxxxxxxxxxxxx ${2:item} of ${1:array}) {",
        "\t$0",
        "}"
      ],
      "description": "我自己定义的cc哦, 厉害吧"
  }
}

image.png
image.png

  1. prefix就是快捷选择栏里面显示的名字, 也是你输入的字符的匹配文字
  2. body里面是我们定义的模板体
  3. ${1:array} 这里的意思是, 光标在生成模板的时候的所在位置的顺序, 当你点击tab的时候鼠标会依次出现在1,2,3这三个地方厉害吧.
有了这个功能, 与你开发的插件来个小配合, 才叫真正的快捷开发代码.

十三. 左侧标签与结构

这个就只需要两个配置对象, 并且有一张你的icon图标.

    "viewsContainers": {
        "activitybar": [
            {
                "id": "xingqiu",
                "title": "标题,并且hover显示",
                "icon": "./images/星球.png"
            }
        ]
    },
    "views": {
        "xingqiu": [
            {
                "id": "c1",
                "name": "超脱:踏天"
            },
            {
                "id": "c2",
                "name": "超脱:道无涯"
            },
            {
                "id": "c3",
                "name": "超脱:道源"
            },
            {
                "id": "c4",
                "name": "超脱:永恒"
            }
        ]
    }

image.png
image.png

  1. activitybar里面会按照id调用对应的views视图
  2. xingqiu只有一个对象则完全占领, 多个的话就是平分这里的面积
  3. 展开的时候会抢面积, 点击折叠起来就好了

十四. 树结构, 官网例子的缺乏,也没有对api进行有效的讲解(重点)

先把最终的效果图放在这里, 我们按图索骥.....
image.png

第一步: 新建tree.js文件, 在这里编写树形视图的代码.

module.exports = vscode.window.createTreeView('c1', {
    treeDataProvider: aNodeWithIdTreeDataProvider(),
    showCollapseAll: true
  });
  1. createTreeView的第一个参数是id, 也就是我们views中定义的id.

2.aNodeWithIdTreeDataProvider方法会生成一个'对象', 用来定义与生成tree的展示效果, 接下来我们会详细的讲.

  1. showCollapseAll选项全部折叠

重点讲讲aNodeWithIdTreeDataProvider
其中有三个key, 其中两个这里重点讲一下.

第一个: getChildren方法, 这里可以理解为获取数据源, 也就是树形数据, 但是他的理念是每次点击会获取一次子集数据, 比如{ a:{name:'xx'} }, 那么点击a的时候会返回{name:'xx'}这个对象, 注意:第一次执行是undefined 所以我们要在第一次执行的时候我我们定义好的树形数据传进来.

上代码:

const {c1Tree} = require('./treeData');
aNodeWithIdTreeDataProvider(){
getChildren: (el) => {
    const arr = [];
    const tree = el || c1Tree;
    for (let item in tree) {
      const activeItem = tree[item];
      if (typeof activeItem !== 'object') {
        arr.push(`${item}:${activeItem}`)
      } else {
        Object.defineProperty(activeItem, "_cc_key", {
          get: function () { return item },
          enumberable: false
        });
        arr.push(activeItem)
      }
    }
    return arr
  },
 }

./treeData.js代码如下, 这只是我当前的格式, 明白了原理你当然可以定制属于你们团队的代码啦.

const c1Tree = {
  '1': {
    '作者': "lulu",
      '宠物': {
        '名字': 'cc',
        '品种':'金毛',
        '年龄': 6,
      }
  },
  '2': {
    '作者': "lulu2",
      '宠物': {
        '名字': 'cc2',
        '品种':'金毛',
        '年龄': 9,
    }
  },
  '3': '单独的字符串'
}

module.exports = {
  c1Tree,
}
原理解析
  1. getChildren返回的是个数组
  2. getChildren返回值的每一项显示在界面上时, 都会传递给getTreeItem做处理
  3. 其实在这个函数里面我们要做的就是把数据处理成getTreeItem方便使用的形式, 这里不做具体的界面输出操作.
  4. 这里我把每个'对象数据'都赋予了_cc_key这样一个属性, 这是为了方便下面取用, 下面讲完getTreeItem我会说一下还有哪些做法.

第一个: getTreeItem方法, 每次用户点击一个下拉的项, 都会在这个方法里面获得这个项的配置.

getTreeItem: (el) => {
    let treeItem = {};
    if (typeof el === 'string') {
      treeItem = {
        label: el,
        collapsibleState: 0,
        tooltip: "hover: 单纯的字符串 ",
        // id: new Date().getTime()
      }
    } else {
      treeItem = {
        label: el._cc_key,
        collapsibleState: 1,
        tooltip: "hover: 可展开 ",
        // id: new Date().getTime()
      }
    }
    return treeItem;
  },

image.png

  1. label 界面上显示的文字
  2. collapsibleState 是否可展开, 也就是是否有子集可点击
  3. tooltip hover上时显示的提示信息
  4. id注册一个唯一标识, 这个可以不写, 如果写的话要保证id的唯一性.
  5. vscode.TreeItemCollapsibleState.None 就是不可折叠, 比直接用0更安全.
  6. vscode.TreeItemCollapsibleState.Collapsed可折叠可展开.

第三个: getParent 获取父级, 但是这次没用到这个就先不详细展开了.

完整代码如下:

const vscode = require('vscode');
const {c1Tree} = require('./treeData');

module.exports = vscode.window.createTreeView('c1', {
    treeDataProvider: aNodeWithIdTreeDataProvider(),
    showCollapseAll: true
  });
  
  function aNodeWithIdTreeDataProvider() {
    return {
      getChildren: (el) => {
        const arr = [];
        const tree = el || c1Tree;
        for (let item in tree) {
          const activeItem = tree[item];
          if (typeof activeItem !== 'object') {
            arr.push(`${item}:${activeItem}`)
          } else {
            Object.defineProperty(activeItem, "_cc_key", {
              get: function () { return item },
              enumberable: false
            });
            arr.push(activeItem)
          }
        }
        return arr
      },
      getTreeItem: (el) => {
        let treeItem = {};
        if (typeof el === 'string') {
          treeItem = {
            label: el,
            collapsibleState: 0,
            tooltip: "hover: 单纯的字符串 ",
          }
        } else {
          treeItem = {
            label: el._cc_key,
            collapsibleState: 1,
            tooltip: "hover: 可展开 ",
          }
        }
        return treeItem;
      },
      getParent: () => {
        return {}
      }
    };
  }
  
  1. 添加_cc_key属性是因为不想被for in的时候循环出来
  2. 可以用'冻结属性'的方式禁止获取
  3. 可以用属性禁止循环出来的方式禁止获取
  4. getChildren里面把字符串组装成 'key: value'的形式, 把对象添加_cc_key属性, 因为对象前面的key之后就无法取到了, 需要这里放入对象.

这样一个树形结构就完成了, 是不是整体逻辑感觉不是那么顺畅, 我也不知道vscode为啥这样设计,奇奇怪怪明明有更好的方法...

十五. 注册账号与申请token详细流程

1: 首先要有一个账号, 登录这里https://login.live.com/
需要配置一个邮箱, 地区选择中国.

2: 注册好后可以点击这里https://aka.ms/SignupAzureDevOps

3: 登录好你会看到如下图片, 输入你的项目名称与项目简介, 这里我选择public公开.
image.png

4: 点击 create project 会跳到下面的页面

5: 去配置一个token, 按图里的顺序点击
image.png
image.png
image.png
image.png
这里配置的是最宽松的条件, 因为这样才会没有那些莫名其妙的错误.

这里注意, 点击create之后可能页面没刷出来东西, 可以选择反复刷新页面, 也可以选择重新做一遍上述流程, 因为这里的token只展示一次, 之后是找不到了的, 所以千万要复制下来.

image.png

6: 这里我们就多了一个工程
image.png

十六. 发布与取消发布

vsce是“ Visual Studio代码扩展”的简称,是用于打包,发布和管理VS代码扩展的命令行工具

以后我们打包插件与发布插件都会用到这个小伙子.

npm install -g vsce
方式一. 控制台发布

打开控制台, 输入命令
后面是你登陆者的名字, 这里创建发布者
image.png
image.png
系统会依次让我们输入 名字、邮箱、刚刚获取的token
image.png
这里我改了下名字, 后面会讲这个问题

默认是登录状态的, 但是如果以后我们要切换用户的话要下面的步骤
接下来我们登陆一下 vsce login (publisher name) 登陆开发者
image.png
还需要输入一下token
image.png

问题: 重复了的话会报下面这个错, 就需要我们改一个发布者名字了
image.png

发布

vsce publish 或者 vsce publish -p xxxxxxxxtoken

如果出现报错
1:
image.png
package.json 中添加 "publisher": "发布者的名字",
如果还不行, 我们可以在官网添加这个名称进入团队
image.png

image.png

2: 他自己生成的.md文件不是很合格, 我们先清空

发布成功

image.png

两分钟左右就可以在应用商店搜到了(哈哈,下面的也是我写的demo)
image.png

自己做好的当然要安装一下试试啦
image.png
功能都在一切安好.

方式二. 网站发布

这个也是官方比较推荐的发布方式, 这里我来演示一下(创建发布者账号)
地址是:https://marketplace.visualstudio.com/manage
image.png
输入名字, id会自动相同, 这个id也是唯一的所以要起个好名字.
image.png
这里可以定义你的图标了, 并且可以把相关联的地址信息写上, 这样发布也挺方便。

在这个网站里可以直接配置发布的信息, 更新的操作如下(拖拽更新):
image.png

十七. 打包传递

如果我们直接在代码里发布是不用手动打包的, 如下情况需要手动打包。

  1. 在网站更新升级插件
  2. 插件内部使用, 采用安装包发给对应同学的方式使用

打包命令 vsce package
image.png
会出现如图vsix为后缀的文件。

这个时候我们就可以把它拖拽到网站上去更新我们的包。

想要给别人使用的话如下图:
image.png
然后会弹出文件选择框, 这样就可以实现安装包安装了。

十八. 能做什么, 要做什么。

能做什么的畅想
  1. 一个字典, 每次悬停在某个id上自动寻找对用的含义。
  2. 团队内部组件的快速生成使用代码。
  3. 工作中的各种提示, 比如定时提示你头上的bug数, 这个要让公司给你出接口了哈。
  4. 左侧栏展示今日的任务安排,等等等等的吧
要做什么

其实吧你说它功能强大也对, 但是实际上编辑器就是编辑器, 一些人想要做很多很多功能放在vscode里面,那还不如直接做个桌面端或者网站, 我们做插件因该做尽量方面的功能, 不用过多操作的功能, 更定制化的功能, 这里的优势是可以获取到开发人员当前的编辑状态, 所以一些与此无关,又略显繁琐的工作不建议放在插件里完成。

end

这次就是这样, 希望和你一起进步.


lulu_up
5.7k 声望6.9k 粉丝

自信自律, 终身学习, 创业者