【vscode】vscode插件文件的配置详解


1. package.json

{
  "name": "vscode-extension-for-worktile",
  "repository": "https://github.com/atinc/wt-rd-vscode-extension",
  "displayName": "Worktile",
  "description": "View and operate Worktile resources in Visual Studio Code.",
  "version": "0.1.2",
  "icon": "out/static/images/worktile_logo.jpg",
  "engines": {
    "vscode": "^1.43.0"
  },
  "categories": [
    "Other"
  ],
  // 能在商店看到有那些特性  以及一些快捷键
  "activationEvents": [ 
    "onCommand:worktile.me",
    "onCommand:worktile.search-work-item",
    "onCommand:worktile.open-work-item",
    "onCommand:worktile.open-work-item-tree",
    "onView:worktile-work-items"
  ],
  "main": "./out/extension.js",

  "contributes": {
    // 在vs里面任何一个行为都是一个事件  可以随意定义  前提: 1没有人知道谁会触发 2当触发了之后会做什么 也没有人知道,写完之后可以将事件暴露给用户
    "commands": [
      {
        "command": "worktile.search-work-item",
        // 搜索事件 
        "title": "Search Worktile Work Item" 
      },
      {
        "command": "worktile.open-work-item",
        "title": "Open Worktile Work Item"
      },
      // 打开树事件
      {
        "command": "worktile.open-work-item-tree",
        "title": "Open Worktile Work Item Tree"
      },
      {
        "command": "worktile.me",
        "title": "Me",
        "icon": {
          "dark": "out/static/images/user_dark.svg",
          "light": "out/static/images/user_light.svg"
        }
      },
      // 刷新所有树事件
      {
        "command": "worktile.refresh-work-item-tree",
        "title": "Refresh Whole Tree",
        "icon": {
          "dark": "out/static/images/refresh_dark.svg",
          "light": "out/static/images/refresh_light.svg"
        }
      },
      {
        "command": "worktile.refresh-work-item-tree-node",
        "title": "Refresh Node",
        "icon": {
          "dark": "out/static/images/refresh_dark.svg",
          "light": "out/static/images/refresh_light.svg"
        }
      }
    ],
    // 热键绑定
    "keybindings": [
      {
        "command": "worktile.search-work-item",
        "key": "ctrl+shift+w",
        "mac": "cmd+shift+w"
      }
    ],
    // 左侧的树
    "viewsContainers": {
      "activitybar": [
        {
          "id": "worktile-explorer",
          "title": "Worktile",
          "icon": "out/static/images/worktile_dark.png"
        }
      ]
    },
    // 一块区域就叫一个view,例如左侧的树 目前只有一个,如果后面在增加在新增一个就好
    "views": {
      "worktile-explorer": [
        {
          "id": "worktile-work-items",
          "name": "Dashboard"
        }
      ]
    },
    "menus": {
      // 左侧最上面的图标的配置
      "view/title": [
        {
          "command": "worktile.me",
          "when": "view == worktile-work-items",
          "group": "navigation"
        },
        {
          "command": "worktile.refresh-work-item-tree",
          "when": "view == worktile-work-items",
          "group": "navigation"
        }
      ],
      // 树的图标 -- 可以自定义具体什么时候触发事件 事件要在上面先定义
      "view/item/context": [
        {
          "command": "worktile.refresh-work-item-tree-node",
          "when": "view == worktile-work-items && viewItem != do-not-show",
          "group": "inline"
        }
      ]
    }
  },
  "scripts": {
    "build:sky": "cd sky && npm run build",
    "vscode:prepublish": "npm run compile",
    "sync-static": "cp -r ./src/static ./out/static",
    "compile": "rm -rf ./out && npm run build:sky && tsc -p ./ && npm run sync-static",
    "lint": "eslint src --ext ts",
    "watch": "tsc -watch -p ./",
    "pretest": "npm run compile && npm run lint",
    "test": "node ./out/test/runTest.js"
  },
  "devDependencies": {
    "@types/glob": "^7.1.3",
    "@types/mocha": "^7.0.2",
    "@types/node": "^13.13.14",
    "@types/vscode": "^1.43.0",
    "@typescript-eslint/eslint-plugin": "^2.34.0",
    "@typescript-eslint/parser": "^2.34.0",
    "eslint": "^6.8.0",
    "glob": "^7.1.6",
    "mocha": "^7.2.0",
    "typescript": "^3.9.6",
    "vscode-test": "^1.4.0"
  },
  "dependencies": {
    "@types/lodash": "^4.14.157",
    "@types/request": "^2.48.5",
    "crypto": "^1.0.1",
    "lodash": "^4.17.19",
    "moment": "^2.27.0",
    "query-string": "^6.13.1",
    "reflect-metadata": "^0.1.13",
    "request": "^2.88.2"
  },
  "publisher": "sunjingyun"
}

 

2./src/views/serch-bar.ts

import * as vscode from "vscode";
import * as _ from "lodash";
import { DEFAULT_SEARCH_TEXT, DEFAULT_SEARCH_PLACEHOLDER, DEFAULT_SEARCH_TEXT_FORMAT, SEARCH_WORK_ITEM_CMD } from "../core/constant";
import { WorkItemWebview } from "./work-item-webview";
import { BaseView } from "./base";
import { injectable, inject } from "../modules/container";

@injectable()
export class WorkItemSearchBar extends BaseView {
    @inject()
    private profileWebview!: WorkItemWebview;

    constructor(context: vscode.ExtensionContext) {
        super(context);

        context.subscriptions.push(
            // trigger 事实上会执行onHandler方法
            vscode.commands.registerCommand(SEARCH_WORK_ITEM_CMD, () => this.trigger())
        );
    }

    protected async onHandler(identifier: string): Promise<void> {
        const result = await vscode.window.showInputBox({
            value: DEFAULT_SEARCH_TEXT,
            // 显示的默认的文案
            placeHolder: DEFAULT_SEARCH_PLACEHOLDER,
            validateInput: (input) => {
                // 正则是否能匹配上
                if (input.length > 0 && input.match(DEFAULT_SEARCH_TEXT_FORMAT)) {
                    return "";
                }
                else {
                    return "Bad identifier format";
                }
            }
        });

        if (result && result.length > 0) {
            await this.profileWebview.trigger(result);
        }
    }

    protected onError(error: Error): void {
        vscode.window.showErrorMessage('An exception occurred when opening the search box, please try again');
    }
}

 

3./src/views/tree-provider.ts

        context.subscriptions.push(
            // 注册了一个事件 
            vscode.window.registerTreeDataProvider(WORK_ITEMS_VIEW, this)
        );

 

 

4./src/views/work-item-webview.ts

import * as vscode from "vscode";
import * as _ from "lodash";
import * as moment from "moment";
import { OPEN_WORK_ITEM_VIEW_TYPE, OPEN_WORK_ITEM_CMD, PRODUCT_NAME } from "../core/constant";
import { injectable } from "../modules/container";
import { WorkItemBaseView } from "./base.work-item";

@injectable()
export class WorkItemWebview extends WorkItemBaseView {
    constructor(context: vscode.ExtensionContext) {
        super(context);

        context.subscriptions.push(
            vscode.commands.registerCommand(OPEN_WORK_ITEM_CMD, (identifier: string) => this.trigger(identifier))
        );
    }

    private async createWebview(): Promise<vscode.WebviewPanel> {
        return await vscode.window.createWebviewPanel(
            OPEN_WORK_ITEM_VIEW_TYPE,
            PRODUCT_NAME,
            vscode.ViewColumn.One,
            {
                retainContextWhenHidden: true,  // 是否允许所有生命周期都存在
                enableScripts: true,
                localResourceRoots: [this.getFileURI(this.context)]
            }
        );
    }

    protected async onHandler(identifier: string): Promise<void> {
        if (_.isNil(identifier) || _.isEmpty(identifier)) {
            vscode.window.showInformationMessage('Please specify an valid identifier');
            return;
        }

        const identity = await this.authService.getIdentity();
        const workItem = await this.agileService.getWorkItemByIdentifier(identifier);

        if (_.isNil(workItem) || _.isNil(identity)) {
            vscode.window.showErrorMessage('The work item does not exist or you do not have permission to view the work item');
            return;
        }

        const panel = await this.createWebview();

        panel.title = `#${identifier} - ${PRODUCT_NAME}`;
        panel.iconPath = {
            dark: this.getFileURI(this.context, "images/worktile_dark.png"),
            light: this.getFileURI(this.context, "images/worktile_light.png")
        };
        // 定义监听 可以收到用户的操作,可以发送给webview
        panel.webview.onDidReceiveMessage(
            async message => {
                switch (message.command) {
                    case 'init':
                        panel.webview.postMessage({
                            command: 'init', data: {
                                workItem,
                                identity
                            }
                        });
                        break;
                    case 'setTitle':
                        {
                            const newTitle = message.text as string;
                            const newWorkItem = await this.agileService.setWorkItemProperties(workItem.id, workItem.type, { title: newTitle });
                            if (newWorkItem && newWorkItem.title === newTitle) {
                                vscode.window.showInformationMessage('标题已更新为:' + newTitle);
                            }
                            panel.webview.postMessage({ command: 'refresh', data: { workItem: newWorkItem } });
                        }
                        break;
                    case 'loadStates':
                        {
                            const stateId = message.text;
                            // 调用api来请求数据
                            const states = await this.agileService.getNextStates(workItem.project.type, workItem.type, stateId);

                            panel.webview.postMessage({ command: 'loadStates', data: { states: states } });
                        }
                        break;
                }
            },
            undefined,
            this.context.subscriptions
        );

        panel.webview.html = this.getHTMLTemplate(this.context, panel, "output/index.html");
    }

    protected onError(error: Error): void {
        vscode.window.showErrorMessage('An exception occurred when opening the work-item, please try again');
    };
}

 

 

5. 如果在vscode里引入css、js一些静态资源的时候,不能使用绝对路径和相对路径,只能使用baseurl来设置

 

 

6. this._onDidChangeTreeData.fire 指手动触发刷新,会销毁旧的,在创建新的

vscode.commands.registerCommand(REFRESH_WHOLE_TREE_CMD, async (node: WorktileTreeNode) => this._onDidChangeTreeData.fire(node))

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM