vscode extension Tree view 추가

파쏭쏭계란빡 ㅣ 2024. 10. 21. 02:32

 

개요

사이드바에 아이콘을 클릭했을 때, Explorer에 "Tabs"와 "Bookmarks" 영역이 트리 형식으로 표시를 하고자합니다.

 

탭과 북마크 영역을 Explorer에 표시하려면, 북마크 각각을 VS Code의 트리 뷰로 구현해야 합니다.

 

두 개의 view를 TreeDataProvider를 등록하고, 이를 views에 연결해야합니다.

 

Tree View API

https://code.visualstudio.com/api/extension-guides/tree-view

vscode.window.registerTreeDataProvider

VS Code extension 개발에서 트리 뷰(Tree View)를 등록하는 함수입니다. VS Code의 탐색기(Explorer)나 사이드바 같은 UI에 트리 형식으로 데이터를 표시합니다.

vscode.window.registerTreeDataProvider(viewId: string, treeDataProvider: TreeDataProvider);

 

파라미터

viewId: string

트리 뷰가 등록될 뷰의 ID 입니다.

이 ID는 package.json 파일에서 정의한 뷰의 ID와 일치해야 합니다.

"views": {
  "explorer": [
    {
      "id": "myCustomView",
      "name": "My Custom View"
    }
  ]
}

 

id가 "myCustomView"이므로 viewId는 "myCustomView"가 되어야 합니다.

vscode.window.registerTreeDataProvider('myCustomView', myTreeDataProvider);

 

treeDataProvider: TreeDataProvider

트리 뷰에 데이터를 제공하는 객체입니다.

 

myTreeDataProvider에서 구현되어야 하는 인터페이스

getTreeItem(element: T): TreeItem

  • 트리의 각 아이템을 반환하는 메서드입니다. 여기서 T는 트리 항목의 타입이고, TreeItem 객체를 반환합니다.
  • TreeItem은 각 항목의 라벨, 설명, 아이콘, 확장 가능 여부 등을 정의합니다.

getChildren(element?: T): Thenable<T[]>

  • 특정 트리 항목의 자식 항목을 반환하는 메서드입니다.
  • 최상위 트리 항목을 반환할 때는 element가 undefined로 전달됩니다.
  • 자식 항목이 있다면 배열로 반환하고, 없다면 빈 배열을 반환합니다.

onDidChangeTreeData?

  • 트리 항목이 변경될 때 트리 뷰가 업데이트되도록 이벤트를 발생시킵니다.
  • 트리 항목에 변화가 있을 때 이 이벤트를 트리거하면 트리 뷰가 새로고침됩니다.

 

구현

폴더와 파일

📦src
 ┣ 📜BookmarkProvider.ts
 ┣ 📜extension.ts
 ┗ 📜TabProvider.ts

 

 

TabProvider.ts

import * as vscode from "vscode";

export class TabProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
    private _onDidChangeTreeData: vscode.EventEmitter<
        vscode.TreeItem | undefined | void
    > = new vscode.EventEmitter<vscode.TreeItem | undefined | void>();
    readonly onDidChangeTreeData: vscode.Event<
        vscode.TreeItem | undefined | void
    > = this._onDidChangeTreeData.event;

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

    getChildren(
        element?: vscode.TreeItem
    ): vscode.ProviderResult<vscode.TreeItem[]> {
        if (!element) {
            // Tabs 트리 뷰에 데이터 추가
            return [new vscode.TreeItem("탭 1"), new vscode.TreeItem("탭 2")];
        }
        return [];
    }
}

 

 

BookmarkProvider.ts

import * as vscode from "vscode";

export class BookmarkProvider
    implements vscode.TreeDataProvider<vscode.TreeItem>
{
    private _onDidChangeTreeData: vscode.EventEmitter<
        vscode.TreeItem | undefined | void
    > = new vscode.EventEmitter<vscode.TreeItem | undefined | void>();
    readonly onDidChangeTreeData: vscode.Event<
        vscode.TreeItem | undefined | void
    > = this._onDidChangeTreeData.event;

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

    getChildren(
        element?: vscode.TreeItem
    ): vscode.ProviderResult<vscode.TreeItem[]> {
        if (!element) {
            // Bookmarks 트리 뷰에 데이터 추가
            return [
                new vscode.TreeItem("북마크 1"),
                new vscode.TreeItem("북마크 2"),
                new vscode.TreeItem("북마크 3"),
                new vscode.TreeItem("북마크 4"),
            ];
        }
        return [];
    }
}

 

 

extension.ts에서 TabProvider, BookmarkProvider 등록

import * as vscode from "vscode";
import { TabProvider } from "./TabProvider";
import { BookmarkProvider } from "./BookmarkProvider";

export function activate(context: vscode.ExtensionContext) {
    console.log("🎈🎈🎈🎈 확장 기능 활성화됨!");

    // TabProvider view 등록
    const tabProvider = new TabProvider();
    //views에 들어갈 id는 tab-view
    vscode.window.registerTreeDataProvider("tab-view", tabProvider);

    // BookmarkProvider view 등록
    const bookmarkProvider = new BookmarkProvider();
    //views에 들어갈 id는 bookmark-view
    vscode.window.registerTreeDataProvider("bookmark-view", bookmarkProvider);
}

export function deactivate() {}

 

 

package.json views에 등록하기

...
"contributes": {
    "viewsContainers": {
        "activitybar": [
            {
                "id": "vscode-tabgroup-and-bookmark",
                "title": "Package Explorer",
                "icon": "images/my-icon.svg"
            }
        ]
    },
    //두 개의 뷰 정의한거 등록하기
    "views": {
        "vscode-tabgroup-and-bookmark": [
            {
                "id": "tab-view",  //registerTreeDataProvider의 첫번째 매개변수로 넘긴 id와 일치해야함
                "name": "Tabs",
                "type": "tree"
            },
            {
                "id": "bookmark-view",  //registerTreeDataProvider의 첫번째 매개변수로 넘긴 id와 일치해야함
                "name": "Bookmarks",
                "type": "tree"
            }
        ]
    }
},
...

 

 

전체 package.json

{
    "name": "vscode-tabgroup-and-bookmark",
    "displayName": "grop tab",
    "description": "",
    "version": "0.0.1",
    "engines": {
        "vscode": "^1.94.0"
    },
    "categories": [
        "Other"
    ],
    "activationEvents": [
        "*"
    ],
    "main": "./out/extension.js",
    "contributes": {
        "viewsContainers": {
            "activitybar": [
                {
                    "id": "vscode-tabgroup-and-bookmark",
                    "title": "Package Explorer",
                    "icon": "images/my-icon.svg"
                }
            ]
        },
        //두 개의 뷰 정의한거 등록하기
        "views": {
            "vscode-tabgroup-and-bookmark": [
                {
                    "id": "tab-view",  //registerTreeDataProvider의 첫번째 매개변수로 넘긴 id와 일치해야함
                    "name": "Tabs",
                    "type": "tree"
                },
                {
                    "id": "bookmark-view",  //registerTreeDataProvider의 첫번째 매개변수로 넘긴 id와 일치해야함
                    "name": "Bookmarks",
                    "type": "tree"
                }
            ]
        }
    },
    "scripts": {
        "vscode:prepublish": "npm run compile",
        "compile": "tsc -p ./",
        "watch": "tsc -watch -p ./",
        "pretest": "npm run compile && npm run lint",
        "lint": "eslint src",
        "test": "vscode-test"
    },
    "devDependencies": {
        "@types/vscode": "^1.94.0",
        "@types/mocha": "^10.0.8",
        "@types/node": "20.x",
        "@typescript-eslint/eslint-plugin": "^8.7.0",
        "@typescript-eslint/parser": "^8.7.0",
        "eslint": "^9.11.1",
        "typescript": "^5.6.2",
        "@vscode/test-cli": "^0.0.10",
        "@vscode/test-electron": "^2.4.1"
    }
}
vscode extension Tree view 추가