diff options
| author | Brett Curran <brettjcurran@gmail.com> | 2026-02-12 13:12:07 +1100 |
|---|---|---|
| committer | Brett Curran <brettjcurran@gmail.com> | 2026-02-12 13:12:07 +1100 |
| commit | c6ea6efcbb9e1558d32f4a584d574ab301df41c4 (patch) | |
| tree | 5ddf81c09f7757c2184ddf0e26f65fe4790eb6a1 | |
| parent | b1cff893077f8042c57fa387d057e644877ccc88 (diff) | |
fix vim-like navigation in panes
| -rw-r--r-- | pyproject.toml | 22 | ||||
| -rw-r--r-- | tui.py | 68 |
2 files changed, 44 insertions, 46 deletions
diff --git a/pyproject.toml b/pyproject.toml index b53adf9..152e07a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,3 +7,25 @@ requires-python = ">=3.12" dependencies = [ "textual>=7.5.0", ] + +[tool.bumpversion] +current_version = "0.1.0" +parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)" +serialize = ["{major}.{minor}.{patch}"] +search = "{current_version}" +replace = "{new_version}" +regex = false +ignore_missing_version = false +ignore_missing_files = false +tag = true +sign_tags = false +tag_name = "v{new_version}" +tag_message = "Bump version: {current_version} → {new_version}" +allow_dirty = false +commit = true +message = "Bump version: {current_version} → {new_version}" +moveable_tags = [] +commit_args = "" +setup_hooks = [] +pre_commit_hooks = [] +post_commit_hooks = [] @@ -8,18 +8,6 @@ import os import subprocess -def get_git_version(): - try: - # git describe --tags --always --dirty - # Returns things like: "v1.0.2-4-g9a2b3c" or "v1.0.2" - return subprocess.check_output( - ["git", "describe", "--tags", "--always", "--dirty"], - stderr=subprocess.DEVNULL - ).decode("utf-8").strip() - except (subprocess.CalledProcessError, FileNotFoundError): - return "dev" - - # --- MOCK DATA GENERATOR (Creates fake files for testing) --- def create_mock_files(): root = Path("mock_campaign") @@ -47,39 +35,14 @@ def create_mock_files(): class CampaignTree(DirectoryTree): """A DirectoryTree with Vim-like navigation.""" - # TODO: Bindings do not actually work to navigate the tree. BINDINGS = [ - Binding("h", "collapse_or_parent", "Collapse / Up"), - Binding("l", "expand_node", "Expand"), - # j and k are built-in to DirectoryTree for navigation, so we don't need to add them + # Map Vim keys to standard Tree actions + Binding("j", "cursor_down", "Down", show=False), + Binding("k", "cursor_up", "Up", show=False), + Binding("h", "cursor_left", "Collapse / Parent", show=True), + Binding("l", "cursor_right", "Expand / Child", show=True), ] - def action_collapse_or_parent(self): - """Collapse node or jump to parent.""" - node = self.cursor_node - if not node: - return - - if node.is_expanded: - node.collapse() - elif node.parent: - # Jump to parent logic - target_node = node.parent - # Find the line number of the parent - current_line = self.cursor_line - while current_line > 0: - current_line -= 1 - if self.get_node_at_line(current_line) == target_node: - self.cursor_line = current_line - self.scroll_to_line(current_line) - break - - def action_expand_node(self): - """Expand the current node.""" - node = self.cursor_node - if node and node.allow_expand and not node.is_expanded: - node.expand() - class FileTable(DataTable): """A DataTable with custom file selection actions.""" @@ -91,6 +54,8 @@ class FileTable(DataTable): BINDINGS = [ Binding("space", "toggle_select", "Select/Deselect"), Binding("a", "toggle_all", "Select All"), + Binding("j", "cursor_down", "Down", show=False), + Binding("k", "cursor_up", "Up", show=False), # Category Shortcuts Binding("s", "set_category('Scenes')", "Set: Scenes"), Binding("t", "set_category('Tokens')", "Set: Tokens"), @@ -222,6 +187,17 @@ class PublisherApp(App): ("q", "quit", "Quit"), ] + def get_git_version(self): + try: + # git describe --tags --always --dirty + # Returns things like: "v1.0.2-4-g9a2b3c" or "v1.0.2" + return subprocess.check_output( + ["git", "describe", "--tags", "--always", "--dirty"], + stderr=subprocess.DEVNULL + ).decode("utf-8").strip() + except (subprocess.CalledProcessError, FileNotFoundError): + return "dev" + def compose(self) -> ComposeResult: """Create child widgets for the app.""" yield Header(show_clock=True) @@ -233,7 +209,7 @@ class PublisherApp(App): yield Static(" Directory Browser", classes="pane-header") # Start at current directory or mock directory start_path = "./mock_campaign" if os.path.exists("./mock_campaign") else "." - yield DirectoryTree(start_path, id="tree_view") + yield CampaignTree(start_path, id="tree_view") # Right Pane: Data Table with Container(id="right_pane"): @@ -248,10 +224,10 @@ class PublisherApp(App): def on_mount(self) -> None: """Called when app starts.""" - version_str = get_git_version() - self.title = f"FVTT PUBLISH v{version_str}" + version_str = self.get_git_version() + self.title = f"FVTT PUBLISH {version_str}" - table = self.query_one(DataTable) + table = self.query_one(FileTable) table.cursor_type = "row" # DEFINING EXPLICIT KEYS HERE IS THE MAGIC SAUCE |
