Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Command on TreeViewItem item click, VSCode Extension

Context: a question related to building a clickable edit button on any item of a TreeView.

How can I call a callback function when the edit button in front of a TreeViewItem is clicked?

Image of the edit button: https://code.visualstudio.com/api/extension-guides/tree-view#view-actions

I noticed the command property on the TreeItem instance and went through the docs but couldn't understand how to call a callback function with the command.

Any help would be appreciated. Thanks

Docs: https://code.visualstudio.com/docs/extensionAPI/vscode-api#TreeItem

"view/item/context": [
    {
        "command": "issuesList.deleteEntry",
        "when": "view == issuesList && viewItem == dependency",
        "group": "inline"
    },
    {
        "command": "issuesList.viewInVisualizer",
        "when": "view == issuesList && viewItem == dependency"
    }
]
like image 568
Amir Moghadam Avatar asked Jan 22 '26 22:01

Amir Moghadam


2 Answers

Better later than never :)

Implement Updateable, Interactive vscode.TreeView

  1. Contribute TreeView Update Command
  2. Contribute View Object
  3. Contribute View Update Button
  4. Create & Register the TreeView class
  5. Activate

Contribute TreeView Update Command

Add command contribution to package.json

{
    "contributes": {
        "commands": [
            {
                "command": "Update-TreeView",
                "category": "Custom",
                "title": "Actively updates the tree view",
                "icon": "$(extensions-refresh)"
            }
        ]
    }
}

Contribute View Object

Add view contribution to package.json

{
    "contributes": {
        "views": {
            "explorer": [
                {
                    "id": "customView",
                    "name": "Custom View"
                }
            ]
        }
    }
}

Contribute View Update Button

Add button contribution for customView to package.json. Please note that we assigned the update command we have contribute earlier.

{
    "contributes": {
        "menus": {
            "view/title": [
                {
                    "command": "Update-TreeView",
                    "when": "view == customView",
                    "group": "navigation"
                }
            ]
        }
    }
}

Create & Register the TreeView class

Code Breakdown

  1. refresh - fires when the refresh button is clicked on the view. We achieved that by registering the update command and fire the update event when invoking it.
  2. getChildren - this is the logic by which you will build your tree.
  3. register - a wrapper method for registering the tree provider and the update command.
  4. withProgress - will show a progress bar while your tree is loaded/updated.
  5. TreeItem - a class for creating the tree items.

Important!

Please check the events under register method. They will fire when you perform actions on your tree. In order to get the TreeItem(s) on which the action was preformed, call e.selection or e.element.

Create a new file custom-tree.ts and paste the following code inside

import * as vscode from 'vscode';

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

    refresh(): void {
        this._onDidChangeTreeData.fire();
    }

    getTreeItem(element: TreeItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
        return element;
    }

    getChildren(element?: TreeItem | undefined): vscode.ProviderResult<TreeItem[]> {
        return vscode.window.withProgress({ location: { viewId: "customView" } }, () => {
            return new Promise<TreeItem[]>((resolve) => {
                let file = new TreeItem('file.txt', vscode.ThemeIcon.File, undefined);
                let folder = new TreeItem('Parent', vscode.ThemeIcon.Folder, [file]);

                resolve([folder]);
            });
        });
    }

    public register(context: vscode.ExtensionContext): any {
        // setup
        const options = {
            treeDataProvider: this,
            showCollapseAll: true
        };

        // build
        vscode.window.registerTreeDataProvider('customView', this);
        vscode.commands.registerCommand('Update-TreeView', () => {
            this.refresh();
        });

        // create
        const tree = vscode.window.createTreeView('customView', options);
        
        // setup: events
        tree.onDidChangeSelection(e => {
            console.log(e); // breakpoint here for debug
        });
        tree.onDidCollapseElement(e => {
            console.log(e); // breakpoint here for debug
        });
        tree.onDidChangeVisibility(e => {
            console.log(e); // breakpoint here for debug
        });
        tree.onDidExpandElement(e => {
            console.log(e); // breakpoint here for debug
        });

        // subscribe
        context.subscriptions.push(tree);
    }
}

class TreeItem extends vscode.TreeItem {
    children: TreeItem[] | undefined;
    command?: vscode.Command | undefined;

    constructor(
        label: string,
        iconPath?: string | vscode.Uri | { light: string | vscode.Uri; dark: string | vscode.Uri } | vscode.ThemeIcon,
        children?: TreeItem[] | undefined,
        command?: vscode.Command) {

        super(
            label,
            children === undefined
                ? vscode.TreeItemCollapsibleState.None
                : vscode.TreeItemCollapsibleState.Collapsed);
        this.command = command;
        this.iconPath = iconPath;
        this.children = children;
    }
}

Activate

Add the following code to your activate method under extension.ts.

import * as vscode from 'vscode';
import { CustomTreeDataProvider } from './custom-tree';

export function activate(context: vscode.ExtensionContext) {
  new CustomTreeDataProvider().register(context);
}
like image 102
Gravity API Avatar answered Jan 25 '26 17:01

Gravity API


    const tree = vscode.window.createTreeView('myview', {treeDataProvider: dataProvider, showCollapseAll: true });
    tree.onDidChangeSelection( e => click(e.selection));
like image 31
wr_alan Avatar answered Jan 25 '26 15:01

wr_alan