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

Add filtering support to DirectoryTree #2215

Merged
merged 7 commits into from
Apr 5, 2023
Merged

Conversation

davep
Copy link
Contributor

@davep davep commented Apr 4, 2023

Something that's come up on Discord this week, and something I could very much do with for what I'm working on at the moment: the ability to flexibly filter what goes into a DirectoryTree.

The idea being that it will allow a very flexible method of filtering, which could be as simple as checking extensions, or something like file permissions, or even more complex things like "exclude directories with files of a certain type in them, and also files over a certain size, and only files that are more than 2 weeks old, and...".

A simple example use of this would be to show the same directory, side-by-side, but the right hand side only shows directories and Markdown files, and also ignores any filesystem entries that start with a .).

from pathlib import Path

from typing import Iterable

from textual.app        import App, ComposeResult
from textual.containers import Horizontal
from textual.widgets    import Header, Footer, DirectoryTree

class MDDirectoryTree(DirectoryTree):

    def filter_paths(self, paths: Iterable[Path]) -> Iterable[Path]:
        """Filter the paths before adding them to the tree.

        Args:
            paths: The paths to be filtered.

        Returns:
            The filtered paths.
        """
        return [
            path for path in paths
            if not path.name.startswith( "." ) and path.is_dir() or (
                    path.is_file() and path.suffix == ".md"
            )
        ]

class DirTreeFilter( App[ None ] ):

    CSS = """
    DirectoryTree {
        width: 1fr;
    }
    """

    def compose( self ) -> ComposeResult:
        yield Header()
        yield Horizontal(
            DirectoryTree("."),
            MDDirectoryTree(".")
        )
        yield Footer()

if __name__ == "__main__":
    DirTreeFilter().run()

Screenshot 2023-04-05 at 20 53 57

@davep
Copy link
Contributor Author

davep commented Apr 5, 2023

Another change I'd like to make is to allow the reloading of the tree. It would be handy to be able to ask a directory tree, without needing to remove and mount a fresh one, to start again from a different root location. I notice that DirectoryTree.path seems to get set, is mutable, but is (as far as I can see) never used again. I'm thinking it might be a good idea to turn this into a setter/getter so that if the developer sets DirectoryPath.path it clears the tree, sets the new root, and populates again.

Edit to add: this should go into a followup PR.

@davep davep changed the title Idea: DirectoryTree flexible filtering Add filtering support to DirectoryTree Apr 5, 2023
@davep davep marked this pull request as ready for review April 5, 2023 19:56
@davep davep merged commit a7c0a79 into Textualize:main Apr 5, 2023
@davep davep deleted the dirtree-filter branch April 5, 2023 20:48
@davep davep mentioned this pull request Apr 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants