Last active
January 20, 2024 10:41
-
-
Save vadviktor/f30571147142577900313e76e823e6d3 to your computer and use it in GitHub Desktop.
Traversing folders using Textual
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pathlib import Path | |
from textual import events, on | |
from textual.app import App, ComposeResult | |
from textual.containers import Container, Horizontal | |
from textual.screen import ModalScreen | |
from textual.widgets import Button, DataTable, Footer, Header, Label | |
from rich.text import Text | |
class FileInformation(ModalScreen): | |
def __init__(self, file_path: Path): | |
self.file_path = file_path | |
super().__init__() | |
def compose(self): | |
self.title = "File Information" | |
with Container(): | |
yield Label(str(self.file_path)) | |
yield Label(f"Size: {self.file_path.stat().st_size}") | |
with Horizontal(): | |
yield Button("Close", id="close", variant="primary") | |
@on(Button.Pressed) | |
def close_modal(self, event): | |
if event.button.id == "close": | |
self.dismiss() | |
class NavigatorApp(App): | |
CSS_PATH = "main.tcss" | |
BINDINGS = [ | |
("q", "quit", "Quit"), | |
("i", "show_file_information", "Show file information"), | |
] | |
table: DataTable | |
current_path: Path = Path.home() | |
def compose(self) -> ComposeResult: | |
yield Header() | |
yield Footer() | |
self.title = str(self.current_path) | |
self.table = DataTable(cursor_type="row") | |
self.table.add_column("", key="icon") | |
self.table.add_column("Name", key="name", width=20) | |
self.table.add_column("Type", key="type") | |
yield self.table | |
def on_mount(self) -> None: | |
self.list_directory() | |
def action_quit(self): | |
self.exit() | |
def action_show_file_information(self): | |
row_key, _ = self.table.coordinate_to_cell_key(self.table.cursor_coordinate) | |
entry_name = self.table.get_cell(row_key, "name") | |
file_path = self.current_path.joinpath(entry_name) | |
if file_path.is_dir(): | |
return | |
self.push_screen(FileInformation(file_path=file_path)) | |
def on_key(self, event: events.Key) -> None: | |
if event.key == "enter": | |
self.navigate_to_directory() | |
def navigate_to_directory(self): | |
# Get the keys for the row and column under the cursor. | |
row_key, _ = self.table.coordinate_to_cell_key(self.table.cursor_coordinate) | |
# Get the value of the first column of the row. | |
entry_name = self.table.get_cell(row_key, "name") | |
if entry_name == "..": | |
self.navigate_up() | |
self.table.clear() | |
self.list_directory() | |
elif self.current_path.joinpath(entry_name).is_dir(): | |
self.navigate_down(entry_name) | |
self.table.clear() | |
self.list_directory() | |
def navigate_up(self): | |
self.current_path = self.current_path.parent | |
def navigate_down(self, entry_name): | |
self.current_path = self.current_path.joinpath(entry_name) | |
def list_directory(self): | |
self.title = str(self.current_path) | |
files_and_dirs = self.current_path.iterdir() | |
if self.current_path.parent == self.current_path: | |
self.table.add_row("", "-- no parent --", "Directory") | |
else: | |
self.table.add_row("", "..", "Directory") | |
for entry in files_and_dirs: | |
if entry.is_dir(): | |
icon = "📁" | |
entry_type = "Directory" | |
else: | |
icon = "📄" | |
entry_type = "File" | |
self.table.add_row(icon, entry.name, entry_type) | |
if __name__ == "__main__": | |
NavigatorApp().run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DataTable { | |
height: 100%; | |
} | |
FileInformation { | |
align: center middle; | |
} | |
FileInformation > Container { | |
height: auto; | |
width: auto; | |
padding: 1 2; | |
background: $panel; | |
} | |
FileInformation > Container > Horizontal { | |
height: auto; | |
width: auto; | |
} | |
FileInformation > Container > Horizontal > Button { | |
margin: 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment