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

Fix TreeView.reveal() behavior. #12489

Merged
merged 2 commits into from
May 17, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 6 additions & 24 deletions packages/plugin-ext/src/plugin/tree/tree-views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,14 @@ class TreeViewExtImpl<T> implements Disposable {

async reveal(element: T, options?: Partial<TreeViewRevealOptions>): Promise<void> {
await this.pendingRefresh;
const select = options?.select !== false; // default to true
const focus = !!options?.focus;
const expand = typeof options?.expand === 'undefined' ? false : options!.expand;

const elementParentChain = await this.calculateRevealParentChain(element);
if (elementParentChain) {
return this.proxy.$reveal(this.treeViewId, elementParentChain, {
select: true, focus: false, expand: false, ...options
select, focus, expand, ...options
});
}
}
Expand Down Expand Up @@ -308,37 +311,16 @@ class TreeViewExtImpl<T> implements Disposable {
*
* @param element element to reveal
*/
private async calculateRevealParentChain(element: T | undefined): Promise<string[] | undefined> {
private async calculateRevealParentChain(element: T | undefined): Promise<string[]> {
if (!element) {
// root
return [];
}
const parent = await this.options.treeDataProvider.getParent?.(element) ?? undefined;
const chain = await this.calculateRevealParentChain(parent);
if (!chain) {
// parents are inconsistent
return undefined;
}
const parentId = chain.length ? chain[chain.length - 1] : '';
const treeItem = await this.options.treeDataProvider.getTreeItem(element);
if (treeItem.id) {
return chain.concat(treeItem.id);
}
const cachedParentNode = this.nodes.get(parentId);
// first try to get children length from cache since getChildren disposes old nodes, which can cause a race
// condition if command is executed together with reveal.
// If not in cache, getChildren fills this.nodes and generate ids for them which are needed later
const children = cachedParentNode?.children || await this.getChildren(parentId);
if (!children) {
// parent is inconsistent
return undefined;
}
const candidateId = this.buildTreeItemId(parentId, treeItem, false);
if (this.nodes.has(candidateId)) {
return chain.concat(candidateId);
}
// couldn't calculate consistent parent chain and id
return undefined;
return chain.concat(this.buildTreeItemId(parentId, treeItem, false));
}

private getTreeItemLabel(treeItem: TreeItem): string | undefined {
Expand Down