Replies: 1 comment
-
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.
0 replies
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.natsorted
to resolve that.Then I discovered the
DirectoryTree
and 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_directory
function). 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