Reputation: 71
I am writitng a VsCode extension. When the user Right Clicks on an item in the tree view, he gets the popup command, whose actions apply to the previously selected item. In VsCode itself, this isn't the case. RightCliking on New File, for instance, adds a file to the currently highlighted folder (Not the selected one). How can I replicate this behavior in my extensions?
Upvotes: 2
Views: 2610
Reputation: 2726
VS Code automatically passes the matching child of the returned value of TreeDataProvider.getChildren()
(colloquially called a "treeItem node" in the community) as the first param when calling your command.
So if you define a command like this:
commands.registerCommand('myExtension.peelOrange', (orange: Orange) => {
/* do stuff */
})
then just make sure that your TreeDataProvider.getChildren()
looks like the following:
export const orangesTreeDataProvider: TreeDataProvider<Orange> = {
getTreeItem: (elem) => {
return {
contextValue: 'orange',
id: elem.id,
label: `${elem.weight} kg`,
}
},
getChildren: (elem) => {
const oranges: Orange[] = [orange1, orange2, /*...*/]
return oranges
}
}
As already explained, the shape of the param passed in your command will be whatever shape the items in the returned array of getChildren()
have. To keep it simple I've kept it all as type Orange
, but in a real-world use case you may find you need to attach additional metadata and methods on each of those oranges to be available inside getTreeItem()
or the myExtension.peelOrange
command. In such a case that new type would be called OrangeNode
according to the conventions.
Upvotes: 0
Reputation: 71
I found the solution. When registering the command, which the right-click runs, add a parameter which is the Tree Node. When the command is invoked via the menu popup, this tree node will be the highlighted node, and not the selected node. For example replace the code
commands.registerCommand('myExtension.myCommand', () => this.command());
and later on:
command() {
}
with
commands.registerCommand('myExtension.myCommand', command(), this);
and later on:
command(node: TreeNode) {
if (node) {
}
}
The if (node)
is necessary, if the command may be invoked from a different context (like a button), in which case node
would be undefined
.
Upvotes: 2