-
Notifications
You must be signed in to change notification settings - Fork 29.2k
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
Allow programmatically selecting a TreeItem in custom views #30288
Comments
This is a huge limitation, it would be so great to have such a basic feature when working with custom tree views |
Yes, this API would be very useful for code view/navigation extensions. I have an extension with a custom view and it is frequently requested to highlight the node that represents where they are in the file. |
This FR could be tracked by #27823. I have (multi) selection per code in my feature wishlist there. |
I am working on a proposed API for this which will be available for authors to try out in this iteration and the plan to make it available in main API is in next milestone. |
If |
|
In that case, both are needed to mimic the |
Agreed with @Gama11. Will the |
I think having just @pltrant Yes, select will trigger the command. I will think to make it optional or trigger the command only when user did the selection. |
A single api for reveal to optionally include select makes the most sense (I agree with not seeing the benefit of just a select without a reveal). |
@sandy081 would using Probably best as another api, but it would be great to be able to just focus the custom view itself (and whatever element was last selected in it) |
Selecting w/o also revealing a node does make sense. Imagine a file tree with some collapsed and some expanded nodes and you want to select all nodes for a given file type. Do you really want to make all collapsed node visible, only because they are in the selection set? That's a usability nightmare (and I'm assuming here, multi selection is already in). |
@mike-lischke Good point, we can't forget about multi-select, which would completely change the api proposed above |
@eamodio there are multiple variations for reveal like
@mike-lischke Is there any existing real use case to support |
Focus is not a state of a tree item, but belongs to the treeview. Hence there is no need for focus for a tree item. If the notion of a single item is required you would use treeview focus + single selection. Regarding |
While focus does belong to the view not the item, imo allowing the inclusion of focus (optionally) on selection is valuable. But as long as there is an api to focus the view itself, I don't feel it is critical. If I want a command in GitLens to open a commit in the view, it is very likely that the use want it to be focused not just selected -- so that keyboarding works. If that has to be 2 apis -- select the item(s), and then focus the view (which would keep the last selected item(s) that's fine (just less discoverable to an extension dev imo). @sandy081 I think you captured the desired actions and agree that reveal and focus doesn't really make sense -- it would likely be reveal/select/focus in that case. Although once you think about multi-select, it gets a bit more complex. Would you allow multi-reveal? Maybe. Multi-select, definitely. Mutli-focus, doesn't make sense. |
I would propose the following apis (don't consider the names just the ideas): viewFocus() // focuses the view with the last selection preserved -- and keyboard focus should be on the last "active" selected item
viewReveal(item: TreeItem) // reveals the item, doesn't change selection or focus -- can change to an array to support multi-reveal if it makes sense
viewSetItemState(item: TreeItem, state: 'expand' | 'collapse', options: { reveal: boolean = false }) // Expands or collapses an item, and optionally reveals it
viewSetSelection(selection: TreeItem[], options?: { focus: boolean = true, reveal: boolean = true }) // changes the view selection where the first item in the array is the active one and the one that would be focused/revealed To be honest, I don't find Thoughts? P.S. I didn't include anything about this above, but would these apis only allow for you to affect your own views (so maybe on TreeDataProvider) or more global to affect other views -- I'm hoping for the latter, but then each of those apis above either need to take a view id or have some other api, that gets you access to some view proxy-like object. |
@mike-lischke It is obvious that every API will have many examples, but our requirement to introduce an API is driven by the extension authors use cases. Hence asked for your scenario for multi @eamodio Since There will be a namespace window {
/**
* Create and show a new webview.
*
* @param title Title of the webview.
* @param column Editor column to show the new webview in.
* @param options Webview content options.
*/
export function createTreeViewer<T>(id: string, options: { dataProvider: TreeDataProvider<T> }): TreeViewer<T>;
}
export interface TreeViewer<T> extends Disposable {
focus(): TPromise<void>
reveal(element: T, select?: boolean): TPromise<boolean>;
} I think selecting an element without revealing it is not useful. It makes sense in multi-select but in single select, I would expect to show it. I see your request for |
@mike-lischke your feedback is very much appreciated. You can only access views you register and the API will be use case driven. I am sorry that we cannot expose methods thinking that this can be useful in future. Once API is out, it is hard to change, so we want to gather requirements before making it public. Yes, revealing a node is expanding nodes, but it is an implementation detail. I see that, requested authors wanted to have Currently Promise will be returned to signal the completion of the operation. |
@sandy081 Back to the For GitLens, I am thinking about some possible commands, that allow a user to jump to the GitLens view and select a node (i.e. the current branch, or current file, etc), and in some of the cases the user might want the node to be selected, focused, and expanded, and others maybe not -- just selected and focused. So I would definitely like to see an We should also consider that expanding a node could have performance impact/implications too. |
@eamodio By default revealed element will not be expanded. If you have the use case, I am happy to add that option. |
I think it would be useful. Here is a specific case. Currently, you can show the history of a branch in quick picks, but I would also like to have a command that would just find/open that branch and expand it in the GitLens view. Also from that same quickpick menu mentioned, I have a Show in Results which basically shows the GitLens Results view and adds that branch to it, with its history expanded. I had to do it that way, because there was no way for me to focus/select/expand the correct node in the GitLens view itself. So with this feature, I could basically rename that to instead of showing in results, it would just focus/select/expand the branch inside the branches node of the GitLens view. I'm assuming calling reveal on a node that is nested will automatically expand all parents so that it will be visible. Correct? |
On the other hand, this is by far not the first Treeview implementation on this planet and over the decades a set of useful APIs have been defined on many of the previous implementation. It's not that we couldn't come up with a list of properties etc. that would certainly be used in one or the other form. And again: creativity comes from possibilities. If you don't provide certain APIs then users will start doing workarounds and it's pretty hard later to get all the code changed then. No offense intended, but if you only consider APIs that are requrested here and in similar FRs, instead of implementing the common set, it appears pretty short sighted.
Why using a different name then? Expanding a hiearchy is such a common and well known term, it makes no sense to introduce a new one for the same functionality.
Hmm, I prefer properties, because I learned over the past 2 decades that these are the cleaner solution. Up to you of course which developer you want to please.
There is no fine grained API to implement. Either you have a function on the tree view to expand or collapse a node or you have that on the node itself (could also be a function or a property). The work is the same, it's only a matter of good or bad design.
That's leaves me speechless. Such an item is all about state. It has a position, it has a selection state, it has a label, it has an expand state, it has a checked state, it has a visible state, it has an image and more. How can you say you don't want state for a node? Wait, maybe it's a misunderstanding here. You probably mean you don't want state for the vscode internal objects and that's totally fine, if the data model is extension provided and keeps this state instead.
Yes, I saw that and I really wondered why it was implemented that way. It's so pretty unusual and conflicts with simple things like app driven updates. Instead it should be an application provided data source. The model contains everything: hieararchy, nodes + their states, events for notifications etc. The treeview only takes such a model and visualizes that.
And what's so bad about this? Can you explain why you don't want to store state? How do you want to know what to update? If you have no state, you cannot compare what changed and are doomed to update the entire tree for every little change. The impact on performance will be terrible. And don't be suprised: when vscode doesn't provide state then the extensions will implement that. There's no win by rejecting the obvious needs.
And that should be how it is implemented.
Setting
I'd rather prefer to make the data source (model) be an extension provided object that can send out events on various occasions, which are data related. The treeview can do the same for view releated operations (like, when it is done loading the content etc.). And they should coalesce notifications, so that extensions can update hundreds of tree items without refreshing the display a hundred times. |
Here is a specific feature request for GitLens: gitkraken/vscode-gitlens#275 I would like to use the So in the previous branch expand example, I gave, I would use Another option would be to keep the Or have |
@sandy081 will this be making the Feb cut? (seems unlikely at this point) |
@mike-lischke Sorry for late reply. I was bit busy this week with our release stuff. Yes, there are many Tree APIs in the market and they might share some common things and differ in other. We have our own set of protocols to follow before coming up with an API. Naming is always tough. We do multiple rounds of feedback and come up with proper name. In this case the extension author wants to reveal a node to the user which makes it obvious to call it
|
@eamodio Re gitkraken/vscode-gitlens#275 If I understand correctly, you want the nodes to be auto expanded when view loads them? If so, Is not the
It is part of Try it out and provide feedback. |
@sandy081 the view will already be loaded and not expanded. I want to be able to have a command to select and expand the item (sometimes 1 level others all descendants). |
@eamodio Ah ok. So what is the context when this command is invoked in your case? |
There are multiple scenarios.
And those are just a few off the top of my head. I want to make jumping into and around the GitLens views more seamless. |
Current status: Under discussion about how to expose views in the API - #45994 |
Verify that you can use the new |
I've been trying to mimick the
files.autoReveal
behavior of the regular explorer in the Dependency Explorer of the Haxe extension. I can expand the necessary nodes just fine, but I don't think there's any way to scroll to the correct position in the view + highlight the node programmatically right now.From what I can tell, the currently planned enhancements won't help with this (#27823). Could a function for selecting a node be added to API? I think a lot of other extensions would benefit from this as well, Code Outline comes to mind.
The text was updated successfully, but these errors were encountered: