From e3d69eea393e3838e0f80ba2c7ded8ade14583c4 Mon Sep 17 00:00:00 2001 From: Kalebe16 Date: Sun, 22 Feb 2026 10:55:31 -0300 Subject: [PATCH] feat: DirectoryTree expand by path --- src/textual/widgets/_directory_tree.py | 39 +++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/textual/widgets/_directory_tree.py b/src/textual/widgets/_directory_tree.py index 7b94d5da8a..28be227f8d 100644 --- a/src/textual/widgets/_directory_tree.py +++ b/src/textual/widgets/_directory_tree.py @@ -57,7 +57,7 @@ class DirectoryTree(Tree[DirEntry]): DEFAULT_CSS = """ DirectoryTree { - + & > .directory-tree--folder { text-style: bold; } @@ -71,11 +71,11 @@ class DirectoryTree(Tree[DirEntry]): } &:ansi { - + & > .tree--guides { - color: transparent; + color: transparent; } - + & > .directory-tree--folder { text-style: bold; } @@ -453,6 +453,37 @@ def filter_paths(self, paths: Iterable[Path]) -> Iterable[Path]: """ return paths + async def expand_by_path(self, target_path: Path) -> None: + """ + Expands the directory tree to reveal the target path. + + Args: + target_path: The filesystem path to reveal in the tree. + """ + + async def expand_to_target_path_recursively( + current_node: TreeNode, target_path: Path + ) -> None: + for child_node in current_node.children: + child_path = child_node.data.path # Current directory path + + if ( + target_path.is_relative_to(child_path) + or child_path == target_path + ): + child_node.expand() + await asyncio.sleep( + 0.1 + ) # Hack to wait for children to populate + self.move_cursor(node=child_node) + await expand_to_target_path_recursively( + current_node=child_node, target_path=target_path + ) + return + + # Start expanding from the root of the directory tree + await expand_to_target_path_recursively(self.root, target_path) + @staticmethod def _safe_is_dir(path: Path) -> bool: """Safely check if a path is a directory.