|
7 | 7 | import { DisposableObject } from "../common/disposable-object"; |
8 | 8 | import { FileTreeNode } from "../common/file-tree-nodes"; |
9 | 9 | import { App } from "../common/app"; |
| 10 | +import { containsPath } from "../common/files"; |
10 | 11 |
|
11 | 12 | export interface QueryDiscoverer { |
12 | 13 | readonly buildQueryTree: () => Array<FileTreeNode<string>> | undefined; |
@@ -41,6 +42,54 @@ export class QueryTreeDataProvider |
41 | 42 | return this.onDidChangeTreeDataEmitter.event; |
42 | 43 | } |
43 | 44 |
|
| 45 | + /** |
| 46 | + * Retrieves a specific tree view item by its path. If it's not found, returns undefined. |
| 47 | + * |
| 48 | + * @param path The path to retrieve the item for. |
| 49 | + */ |
| 50 | + public getTreeItemByPath(path: string): QueryTreeViewItem | undefined { |
| 51 | + const itemPath = this.findItemPath(path, this.queryTreeItems); |
| 52 | + if (!itemPath) { |
| 53 | + return undefined; |
| 54 | + } |
| 55 | + |
| 56 | + return itemPath[itemPath.length - 1]; |
| 57 | + } |
| 58 | + |
| 59 | + /** |
| 60 | + * Find a specific tree view item by path. |
| 61 | + * |
| 62 | + * @param path The path to find the item for. |
| 63 | + * @param items The items to search. |
| 64 | + * @param currentPath The current path to the item. |
| 65 | + * @return The path to the tree view item, or undefined if it could not be found. The last item in the |
| 66 | + * array is the item itself. |
| 67 | + */ |
| 68 | + private findItemPath( |
| 69 | + path: string, |
| 70 | + items: QueryTreeViewItem[], |
| 71 | + currentPath: QueryTreeViewItem[] = [], |
| 72 | + ): QueryTreeViewItem[] | undefined { |
| 73 | + const relevantItems = items.filter((item) => containsPath(item.path, path)); |
| 74 | + |
| 75 | + const matchingItem = relevantItems.find((item) => item.path === path); |
| 76 | + if (matchingItem) { |
| 77 | + return [...currentPath, matchingItem]; |
| 78 | + } |
| 79 | + |
| 80 | + for (const item of relevantItems) { |
| 81 | + const childItem = this.findItemPath(path, item.children, [ |
| 82 | + ...currentPath, |
| 83 | + item, |
| 84 | + ]); |
| 85 | + if (childItem) { |
| 86 | + return childItem; |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + return undefined; |
| 91 | + } |
| 92 | + |
44 | 93 | private createTree(): QueryTreeViewItem[] { |
45 | 94 | const queryTree = this.queryDiscoverer.buildQueryTree(); |
46 | 95 | if (queryTree === undefined) { |
@@ -95,4 +144,14 @@ export class QueryTreeDataProvider |
95 | 144 | return item.children; |
96 | 145 | } |
97 | 146 | } |
| 147 | + |
| 148 | + public getParent(item: QueryTreeViewItem): QueryTreeViewItem | undefined { |
| 149 | + const itemPath = this.findItemPath(item.path, this.queryTreeItems); |
| 150 | + if (!itemPath) { |
| 151 | + return undefined; |
| 152 | + } |
| 153 | + |
| 154 | + // The item itself is last in the last, so the parent is the second last item. |
| 155 | + return itemPath[itemPath.length - 2]; |
| 156 | + } |
98 | 157 | } |
0 commit comments