umputun/revdiff PR #295 — Configurable tree pane position — PR #295
umputun/revdiff · pull request #295 ·
Transcript
PlainEnglish
Let's walk through pull request two ninety-five for revdiff. This one adds configurable tree pane positioning, giving users control over their layout. Twenty-four files touched, with around two hundred forty-seven additions — it's a thoughtful enhancement that doesn't break anything existing.
PlainEnglish
This PR has two core goals. First, make the tree pane position configurable through the usual channels — command line flag, environment variable, or config file. Second, introduce directional focus actions that adapt to whatever layout the user picks. Along the way, we're updating mouse handling, rendering logic, and documentation. And importantly, we're keeping backward compatibility — the default is still left, so existing users won't see any change unless they opt in.
PlainEnglish
Before this change, the file tree was always locked to the left side. That's fine for most users, but some folks prefer the tree on the right — maybe it fits their workflow better, or they have a particular monitor setup. This PR makes the layout flexible. Users can now configure which side the tree lives on, and the UI adapts — keyboard navigation, mouse clicks, everything just works with the new position. The default is still left, so nothing breaks for anyone who's happy with the current setup.
Architecture
Let's look at how the configuration surface works. We add a new tree position flag to the options struct, with three ways to set it — command line flag, environment variable, or config file. The go-flags library validates the choice, so only left or right is accepted. There's a small helper method that resolves the string to a typed enum constant. This follows the composition-root pattern the codebase already uses — flags are resolved once at startup, then the typed value flows through the system.
Architecture
Here's the heart of the keyboard handling change. We introduce two new actions — focus left and focus right. The default bindings for h and l switch from focus tree and focus diff to these new directional actions. Now when someone presses h, they're saying focus left, not focus tree. At dispatch time, the model looks at the configured tree position and maps focus left to whichever pane is actually on the left. If the tree is on the right, h focuses the diff pane. If the tree is on the left, h focuses the tree. The binding stays the same, but the meaning adapts.
Architecture
Let's visualize how this resolution works. When you press h, the keymap returns focus left. That action flows into the resolve directional focus method. If the tree is on the left, it maps to focus tree. If the tree is on the right, it maps to focus diff. The result is a semantic action that targets the correct pane, regardless of layout. Users can still explicitly bind focus tree or focus diff if they want position-independent behavior — those bypass the mapping entirely.
Architecture
Two other pieces need to adapt to the position — mouse handling and rendering. In mouse.go, we add a helper that calculates the screen column range of the tree pane based on position. The hit-test logic uses that range instead of hardcoding left-side assumptions, so clicks route to the right pane whether the tree is on the left or right. In view.go, the rendering code does a conditional lipgloss join — if the tree is on the right, we join diff pane then tree pane. If it's on the left, we join tree then diff. The layout literally flips.
CodeQuality
The test suite is comprehensive here. We've got config flag tests covering all three sources and validating that invalid values get rejected. Keyboard tests verify that directional keys resolve correctly for both positions, and that explicit semantic bindings bypass the mapping. Mouse tests check hit-testing boundaries at both tree positions, including borders and off-screen clicks. Rendering tests confirm the pane order by checking label positions. And markdown TOC tests make sure the table of contents follows the tree to the configured side. The agent examined all these areas and found them clean.
Architecture
All the documentation gets updated to reflect the new feature. The README adds the tree position flag to the options table and updates language around TOC positioning to say on the configured side instead of on the left. Plugin skills for Claude, Codex, and Pi all get synchronized guidance — pass the flag when the user explicitly requests a side, otherwise respect their config. The site docs mirror the README changes, and the architecture doc renames left-pane navigation to just navigation pane, making the language position-neutral.
PlainEnglish
After this PR lands, users can configure the tree pane position through a flag, an environment variable, or their config file. Directional keybindings dynamically resolve to the correct pane based on layout. Mouse clicks and wheel events route correctly regardless of position. Markdown TOC follows the tree to the configured side. And the default is still left, so existing users see no change unless they opt in. It's a clean, flexible enhancement that respects the user's workflow.
CodeQuality
The agent looked at several potential gotcha areas and found them all handled correctly. Invalid tree position values get rejected by the go-flags choice validation. The default value inheritance chain is tested across all three sources. Config file round-tripping works — the setting persists when you dump config. The tree position is immutable after startup, following the pattern the codebase already uses. And backward compatibility is solid — the default is left, matching the old hardcoded behavior, so existing configs keep working.
PlainEnglish
This is a really nice PR. It adds a feature people will appreciate, does it in a way that fits the existing architecture, covers all the edge cases in tests, and doesn't break anything for users who are happy with the current layout. No gotchas, no open questions — it's ready to merge. Nice work.
How this was made
Lenzon read umputun/revdiff at pull request #295 and generated this walkthrough automatically. The narration above is the transcript of what it says.
Explain a pull request from your own repo
Point Lenzon at a repo or a pull request and get a narrated walkthrough like this one.
Try it