Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pass selected tree item context to view/title commands #42903

Closed
chrisdias opened this issue Feb 4, 2018 · 21 comments · Fixed by #158916
Closed

pass selected tree item context to view/title commands #42903

chrisdias opened this issue Feb 4, 2018 · 21 comments · Fixed by #158916
Assignees
Labels
api api-finalization api-proposal feature-request Request for new features or functionality tree-views Extension tree view issues verification-needed Verification of issue is requested verified Verification succeeded

Comments

@chrisdias
Copy link
Member

chrisdias commented Feb 4, 2018

I would like to have the selected context passed to view commands so that I can act on the selected node in the tree. for example, let's say I want to have a command in the Docker explorer Navigation area (next to where it says "DOCKER" on the sash) that runs the selected image in the tree.

      "view/title": [
        {
          "command": "vscode-docker.explorer.run",
          "when": "view == dockerExplorer",
          "group": "navigation"
        }
      ],

I would register my command:

vscode.commands.registerCommand('vscode-docker.explorer.run', (context?: any, selectedContext?: any[]) => dockerExplorerProvider.run(context, selectedContext));

And then in my command I can get the selected node(s) from the tree

build(context?: any): void {
   if (selectedContext.length >0) {
     // work on multi selected images
   }
  ...
   if (context) {
      // work on selected image
   } else {
      // pop a quick pick to list images
   }
   // ...
}
@sandy081 sandy081 added feature-request Request for new features or functionality tree-views Extension tree view issues labels Feb 5, 2018
@sandy081 sandy081 added this to the Backlog milestone Feb 5, 2018
@sandy081 sandy081 modified the milestones: Backlog, February 2018 Feb 14, 2018
@sandy081 sandy081 modified the milestones: February 2018, March 2018 Feb 27, 2018
@sandy081 sandy081 modified the milestones: March 2018, April 2018 Mar 27, 2018
@sandy081 sandy081 modified the milestones: April 2018, May 2018 Apr 19, 2018
@eamodio
Copy link
Contributor

eamodio commented Apr 30, 2018

I would expand on this to also provide the treeview instance as well as the selected node. I have some generic commands (refresh, close, etc) that I use across a few views, and right now I am required to create new commands for each view (causing a command explosion in package.json and a maintenance issue). It the view was also provided all of that duplication could be eliminated.

I would also love if the treeview was also returned on itself even when executing a command on a node (so that way the node doesn't have to carry around its parent if access is needed).

Overall I keep coming back to this request: #25716 having more/structured context for how commands were invoked makes them much easier to deal with

@d-akara
Copy link

d-akara commented May 5, 2018

@eamodio Could you do something like this? I use an internal command to proxy to functions I want to invoke so I don't have to register every action as a command.

Here is an example snippet of something I use...

let disposable = vscode.commands.registerCommand('dakara-internal.oncommand', (onCommand:Function, ...params) => onCommand.apply(this, params))

function showLine(lineNumber:number) {
    vscode.commands.executeCommand("revealLine", {lineNumber})
}

export function makeTreeItemFromSelection(line: vscode.TextLine) {
    return {
        label:  (line.lineNumber + 1) + ` ${Glyph.TRI_DOT_VERTICAL} ` + line.text,
        command: {title: 'reveal', command: 'dakara-internal.oncommand', arguments: [showLine, line.lineNumber]},
    }
}```

@sandy081 sandy081 modified the milestones: May 2018, Backlog May 28, 2018
@alexr00 alexr00 self-assigned this Oct 7, 2019
@eamodio
Copy link
Contributor

eamodio commented Aug 24, 2020

I would like to re-raise this. I keep hitting this issue more and more often (causing an explosion of unnecessary commands). For example in GitLens, I've been adding a bunch of new views, and each of these views have many overlapping commands in the view/title. But instead of being able to have 1 command for each with additional placements (although with a regex when, I can do it in a single placement too), I have to duplicate the command, exclusion from the command palette, and placement for each command. Then I also need to register multiple commands for each of the views. This is extremely painful.

Where as if the TreeDataProvider provided on the createTreeView call was provided in the command callback (like the view item is provided in the viewItem/context), it would remove the need for all of the duplication, because the commands could be handled more independently.

@eamodio
Copy link
Contributor

eamodio commented Aug 24, 2020

@sbatten This looks like it might be similar to work done here: 4b4931e

@sandy081 sandy081 removed their assignment Aug 25, 2020
@alexr00 alexr00 modified the milestones: Backlog, On Deck Aug 26, 2020
@suparngp
Copy link

suparngp commented Dec 1, 2020

This will be really helpful in removing a lot of redundant commands. For example, I have multiple treeviews and they render some help text in the message. To toggle the message, I have to create one command for each view which refreshes it.

@jrieken
Copy link
Member

jrieken commented Aug 18, 2022

this will cause a breaking change for many of our commands that are registered in the TreeViewPane.

Do you have details on how it broke? Strictly speaking commands should be fit to be called with any argument (since any extension and any keybinding can invoke a command, happens rarely tho). The plan is to build on this assumption and not make this a opt-in change. However, after the last sync we have been discussing to call these commands with just the model objects: T (focused) and ...T[] (selected)

@bwateratmsft
Copy link
Contributor

this will cause a breaking change for many of our commands that are registered in the TreeViewPane.

Do you have details on how it broke? Strictly speaking commands should be fit to be called with any argument (since any extension and any keybinding can invoke a command, happens rarely tho). The plan is to build on this assumption and not make this a opt-in change. However, after the last sync we have been discussing to call these commands with just the model objects: T (focused) and ...T[] (selected)

I think this matches what is currently done for context menu commands on tree items, right?

@nturinski
Copy link
Member

Do you have details on how it broke?

The command that is broken is creating an Azure resource. Here is a link to the issue with a video: microsoft/vscode-azureresourcegroups#363

To understand why this change is problematic for us, let me share a snippet of our code:

export async function createFunctionApp(context: IActionContext & Partial<ICreateFunctionAppContext>, subscription?: AzExtParentTreeItem | string, newResourceGroupName?: string): Promise<string> {
    let node: AzExtParentTreeItem | undefined;
    if (typeof subscription === 'string') {
        node = await ext.rgApi.tree.findTreeItem(`/subscriptions/${subscription}`, context);
        if (!node) {
            throw new Error(localize('noMatchingSubscription', 'Failed to find a subscription matching id "{0}".', subscription));
        }
    } else if (!subscription) {
        node = await ext.rgApi.tree.showTreeItemPicker<AzExtParentTreeItem>(SubscriptionTreeItem.contextValue, context);
    } else {
        node = subscription;
    }

Ignoring the context that we inject into all of our commands, the new { selectedTreeItems: T[] } breaks us because if we have no subscription arg, we will prompt the user for it. However, the new argument is causing our code to always fall into the else condition because that argument is no longer undefined even though nothing is selected. We account for the following entry points:

  1. Right-clicking a subscription node: we will use that selected T model
  2. Programmatically calling the command from code with the subscription id
  3. The command palette: where the target will be undefined
  4. The TreeViewPane + button: the target previously was undefined, but now always has an object with property selectedTreeItems whether that array is empty or not

The plan is to build on this assumption and not make this a opt-in change. However, after the last sync we have been discussing to call these commands with just the model objects: T (focused) and ...T[] (selected)

This assumption will still break us as we currently only handle expected tree items being focused since the previous entry point must have been the context menu command (where we will know which tree items we allow to be focused for the specific commands), but this solution would be highly preferable to the current implementation.

@benibenj
Copy link
Contributor

The release of this feature will be moved to the September iteration to give extensions enough time to adapt.

@alexr00
Copy link
Member

alexr00 commented Sep 19, 2022

@nturinski Have you had a chance to make the changes needed in VS Code Extensions for Azure? We merged this change back into main so it's been in VS Code Insiders for about 2 weeks now.

@nturinski
Copy link
Member

Hi @alexr00

According to our investigation, it seems like the new changes don't break us. Thanks for considering us! 😄

@alexr00
Copy link
Member

alexr00 commented Sep 21, 2022

Great to hear! Closing this issue so that it gets added to our testing for September.

@benibenj
Copy link
Contributor

Verifying:

  1. Register a view/title command (takes 2 arguments) in a panel which has a tree view
  2. set breakpoint in command function
  3. Select tree item(s) and run command from view/title
  4. First argument should always be the focused tree item (type T).
    Second argument should be (all) selected tree items as long as the focused tree item is one of the selected tree items.

The arguments should behave the same as for commands in the context menu.

@irvnriir
Copy link

How to get them ?

doesn't work:

		let test = sy.vscode.commands.registerCommand('Extension_test.test', () => {
			sy.console.log(this.selectedTreeItems)		// `undefined`
		});
		sy.ExtensionDisposables.push(test);

@gjsjohnmurray
Copy link
Contributor

@irvnriir are you using Insiders for this? If not you'll need to wait until 1.72 ships, probably by the end of next week,

@roblourens roblourens added the verified Verification succeeded label Sep 29, 2022
@roblourens
Copy link
Member

roblourens commented Sep 29, 2022

Am I doing it wrong?

	context.subscriptions.push(vscode.commands.registerCommand('extension.helloWorld', async (arg1, arg2) => {
		console.log(arg1, arg2);
	}));

All I get is undefined undefined. Registered it in all view/title, and clicked it everywhere I see it, for example, Explorer and Outline

@roblourens roblourens added verification-steps-needed Steps to verify are needed for verification and removed verified Verification succeeded labels Sep 29, 2022
@benibenj
Copy link
Contributor

Make sure you register the view/title command to a contributed TreeView (for example in Sample Tree Views extension or Pull Requests extension).
Then select an element in the tree (or multiple if multiselect) and press the action. The arguments should then print the focused item and the selected items

@TylerLeonhardt TylerLeonhardt removed the verification-steps-needed Steps to verify are needed for verification label Sep 29, 2022
@roblourens
Copy link
Member

Oh, I see it, thanks

@roblourens roblourens added the verified Verification succeeded label Sep 29, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Nov 5, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api api-finalization api-proposal feature-request Request for new features or functionality tree-views Extension tree view issues verification-needed Verification of issue is requested verified Verification succeeded
Projects
None yet
Development

Successfully merging a pull request may close this issue.