Change:
! repro steps a search that has a compressed node outside of the viewport to keep collapsing gets stuck when trying to collapse all.
repro: the repo folder into a multi-root workspace (where another workspace also has the word "debug" somewhere in it). for the string "debug" clicking the Collapse All button a bunch of times gets stuck after a few times :bug: This is because the tree needs info from the function, which hasn't been run yet since the "compressed" element is off of the view. Therefore, when I'm calling , I eventually get to the "compressed" element that doesn't have the info that I need.
What is the best way to collapse all nodes of a tree at a certain level? My current (buggy) strategy involves iterating through the nodes via and collapsing them based on element types, but that depends on knowing the parent-most node in a compression (which I store when I use ).
This is strange. Despite the elements never being rendered, the tree should know exactly which elements have been compressed. The function should never create any state that other code depends on... it's purely a rendering function. At a glance the problem seems to be that you're modifying the tree (collapsing element) as you iterate it (using navigator). Can you refactor that action such that it first collects all elements which should be collapsed and, once all are collected, calls on each?
oops, figured it out! Follow-up question: how do I collapse part of a compressed node? (ie: collapsing so that only the parent is visible?) I tried calling on the parent element and it seems to assume that I just want the existing compressed node collapsed.
Unsure what you mean. Take this example: ! In this scenario, , and are just one node, for all purposes. Do you mean you want to collapse , for example? What should be the visual outcome of that?
Yes, I'd be talking about collapsing or . Now that you mention it, it would be confusing to collapse partway like that. The reason I bring this up is because the "collapse/expand` button in search is multi-step in multi-root and tree modes. Ie: in multi-root, the collapse/expand would go: collapse button once: collapses all nodes one level below root collapse again: collapses all root nodes. everything. and repeat How would you imagine that it should handle the first collapse if it's a compressed series of folders (ie: )? I was originally thinking that it would just compress , but that would have a weird visual outcome. Do you know anywhere else where we do something like this?
I would expect the node would be collapsed in that case. The key here is nodes, not folders. The node represents three folders.

Discussion:
let nodeToTest = node; if (node instanceof FolderMatch) { <del> nodeToTest = node.compressionStartParent ?? node; </del> <ins> const compressionStartNode = viewer.getCompressedTreeNode(node).element?.elements[0]; // Match elements should never be compressed, so !(compressionStartNode instanceof Match) should always be true here nodeToTest = (compressionStartNode && !(compressionStartNode instanceof Match)) ? compressionStartNode : node; </ins> } const immediateParent = nodeToTest.parent();

renderCompressedElements(node: ITreeNode<ICompressedTreeNode<FolderMatch>, any>, index: number, templateData: IFolderMatchTemplate, height: number | undefined): void { const compressed = node.element; const folder = compressed.elements[compressed.elements.length - 1]; <del> folder.compressionStartParent = compressed.elements[0]; </del> const label = compressed.elements.map(e => e.name()); if (folder.resource) {

renderElement(node: ITreeNode<FolderMatch, any>, index: number, templateData: IFolderMatchTemplate): void { const folderMatch = node.element; <del> folderMatch.compressionStartParent = undefined; </del> if (folderMatch.resource) { const workspaceFolder = this.contextService.getWorkspaceFolder(folderMatch.resource); if (workspaceFolder && isEqual(workspaceFolder.uri, folderMatch.resource)) {

private _replacingAll: boolean = false; private _name: Lazy<string>; <del> // if this is compressed in a node with other FolderMatches, then this is set to the parent where compression starts public compressionStartParent: FolderMatch | undefined; </del> constructor( protected _resource: URI | null, private _id: string,