Replies: 1 comment 1 reply
-
I haven't tested thoroughly, but this seemed to work for me? from pathlib import Path from typing import override from natsort import natsorted from textual import work from textual.app import App, ComposeResult from textual.widgets import DirectoryTree from textual.widgets.directory_tree import DirEntry from textual.widgets.tree import TreeNode from textual.worker import get_current_worker class CustomDirectoryTree(DirectoryTree): @override @work(thread=True, exit_on_error=False) def _load_directory(self, node: TreeNode[DirEntry]) -> list[Path]: assert node.data is not None path = node.data.path path = path.expanduser().resolve() return natsorted( self.filter_paths(self._directory_content(path, get_current_worker())), key=lambda path: (not self._safe_is_dir(path), path.name.lower()), ) class ExampleApp(App): def compose(self) -> ComposeResult: yield CustomDirectoryTree(path="./") if __name__ == "__main__": app = ExampleApp() app.run() |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
TL;DR: Update
DirectoryTree._load_directory()to usenatsort.natsorted()or similar in place ofsorted(), so paths with numbers are sorted the way humans expect. If controllability/compatibility is desired, add an attribute that pivots between calling the built-insorted()and some natural-sort algorithm.I have been trying all day to get a Tree to sort elements the way I wanted. I initially implemented my own flavor of a DirectoryTree before I realized it already existed. In my implementation, I walked the filesystem and added nodes to the tree manually, which meant I had full control over the sorting. At first I just used
sorted()to get a stable view, but ended up adding a key function to sort directories first. Then I noticed that paths with numbers were sorted lexicographically instead of numerically, so I usednatsort.natsortedto resolve that.Then I discovered the
DirectoryTreeand thought I could eliminate a bunch of unnecessary code, and probably be way more efficient by using it. I did not realize that it performs a sort on the paths while loading, so I was fighting with it to get my naturally sorted directories/files back. Eventually I realized that even if I went back to plainsorted(), the directories stayed above the files! That's when I dug into the source code and found that_load_directory()is callingsorted(filter_paths(...), key=...)which means anything I do to change the order in the filtering function is blown away by this new sorting call.I then tried a bunch of things to bypass this, but I couldn't get them to work (for example, overriding the
_load_directoryfunction). All I really need is for thatsorted()call to benatsorted()or similar, and I could just use the native DirectoryTree as-is.Beta Was this translation helpful? Give feedback.
All reactions