@@ -292,29 +292,33 @@ def _set_node_visibility(
292292 ancestor_ids : set ,
293293 visible : bool ,
294294 ) -> None :
295- """Recursively set node visibility."""
295+ """Recursively set node visibility by removing non-matching nodes."""
296+ # Collect nodes to remove (can't modify children while iterating)
297+ nodes_to_remove : list [Any ] = []
298+
296299 for child in node .children :
297300 child_id = id (child )
298301 is_match = child_id in match_ids
299302 is_ancestor = child_id in ancestor_ids
300303 should_show = is_match or is_ancestor or not self ._tree_filter_query
301304
302- # Use display style to hide/show
303- # Note: Textual Tree doesn't have per-node visibility,
304- # so we'll dim non-matching nodes instead
305305 if not should_show and self ._tree_filter_query :
306- # Dim non-matching nodes
307- original = self . _tree_original_labels . get ( child_id , str ( child . label ) )
308- if child_id not in self . _tree_original_labels :
309- self . _tree_original_labels [ child_id ] = original
310- child . set_label ( f"[dim] { escape_markup ( self ._get_node_label_text (child )) } [/]" )
306+ # Mark for removal
307+ nodes_to_remove . append ( child )
308+ else :
309+ # Recurse into visible nodes
310+ self ._set_node_visibility (child , match_ids , ancestor_ids , should_show )
311311
312- self ._set_node_visibility (child , match_ids , ancestor_ids , should_show )
312+ # Remove non-matching nodes
313+ for child in nodes_to_remove :
314+ try :
315+ child .remove ()
316+ except Exception :
317+ pass
313318
314319 def _show_all_tree_nodes (self : TreeFilterMixinHost ) -> None :
315- """Show all tree nodes (remove filter dimming)."""
316- # Labels are restored by _restore_tree_labels
317- pass
320+ """Rebuild the tree to restore all nodes after filtering."""
321+ self .refresh_tree ()
318322
319323 def _restore_tree_labels (self : TreeFilterMixinHost ) -> None :
320324 """Restore original labels for all modified nodes."""
0 commit comments