Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to listen to events in vscode's TreeDataProvider?

I'm playing with building a vscode extension, using the TreeDataProvider API. I have a list of things showing, each TreeItem a composed label string, all works fine.

What I am missing is a way of reacting to click events on any of the items. VSCode selects the item when you click on it, but I'd like to listen to that event, get the item in question etc... It's not obvious to me from the docs.

In general, customizing the TreeItem is severely lacking, e.g. being able to colorize the label or pass a more flexible UI component in instead of just a string... Maybe I'm missing something?

like image 932
batjko Avatar asked Jun 10 '18 21:06

batjko


1 Answers

VSCode selects the item when you click on it, but I'd like to listen to that event, get the item in question etc...

You can use TreeItem.command to run some command when a tree item is selected, and then register a callback for that command. Here's a simple example that traces the label of a tree item to the console:

'use strict';
import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
    vscode.window.registerTreeDataProvider("exampleTreeView", new ExampleTreeProvider());
    vscode.commands.registerCommand("exampleTreeView.selectNode", (item:vscode.TreeItem) => {
        console.log(item.label);
    });
}

export class ExampleTreeProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
    getTreeItem(element: vscode.TreeItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
        return element;
    }

    getChildren(element?: vscode.TreeItem): vscode.ProviderResult<vscode.TreeItem[]> {
        if (element == null) {
            var item = new vscode.TreeItem("Foo");
            item.command = {
                command: "exampleTreeView.selectNode",
                title: "Select Node",
                arguments: [item]
            };
            return [item];
        }
        return null;
    }
}
"contributes": {
    "views": {
        "explorer": [
            {
                "id": "exampleTreeView",
                "name": "Example Tree View"
            }
        ]
    }
},

The command can be any arbitrary string, but I like to "scope" it by prefixing the view ID. It's important to pass the item itself via arguments if you want to access any of its properties in the callback.

In general, customizing the TreeItem is severely lacking, e.g. being able to colorize the label or pass a more flexible UI component in instead of just a string...

That sounds like an accurate assessment, the API is a bit limiting in some ways. If you need more freedom, the recently introduced Webview API might be a good alternative. Note that that would mean implementing your own tree view from scratch using HTML/CSS/JS.

like image 98
Gama11 Avatar answered Nov 10 '22 06:11

Gama11