Skip to content

feat(editor): split pane support for editor tabs#998

Open
SinanGncgl wants to merge 8 commits into
crynta:mainfrom
SinanGncgl:feat/editor-split-panes
Open

feat(editor): split pane support for editor tabs#998
SinanGncgl wants to merge 8 commits into
crynta:mainfrom
SinanGncgl:feat/editor-split-panes

Conversation

@SinanGncgl

@SinanGncgl SinanGncgl commented Jul 13, 2026

Copy link
Copy Markdown

Extends the existing terminal pane tree system to editor tabs so users
can view different files side by side.

  • Cmd/Ctrl+D / Cmd/Ctrl+Shift+D split editor pane right / down
  • Cmd/Ctrl+[ / Cmd/Ctrl+] cycle focus between editor panes
  • Cmd/Ctrl+W with multiple panes closes the active pane only
  • Clicking a file in the explorer loads it into the focused split pane
    (falls back to new tab when the pane has unsaved changes)

No existing behavior changed. Single-pane editor tabs and all terminal
behavior are identical to before.

New unit tests cover split, close, and focus-after-close tree transforms
for editor pane trees (src/modules/tabs/lib/editorPanes.test.ts).

What

Editor tabs now support split panes, reusing the same PaneNode tree
infrastructure that already powers terminal splits. Each pane is
independent and can show a different file. A new EditorPaneTreeView
component (mirror of PaneTreeView) handles recursive rendering with
resizable panels.

Why

Addresses the "multiple editors side by side" use case from #533.
The pane tree system in panes.ts was already generic with no
terminal-specific logic, making this a natural extension.

How

  • Added path? to PaneNode leaf and two new utilities (findLeafPath,
    setLeafPath) in panes.ts
  • Extended EditorTab with paneTree: PaneNode and activeLeafId
  • Extended splitActivePane, closeActivePane, closePaneByLeaf,
    focusPane, focusNextPaneInTab in useTabs to handle editor tabs
    alongside the unchanged terminal branches
  • Created EditorPaneTreeView.tsx mirroring PaneTreeView.tsx
  • Updated EditorStack to render via the pane tree instead of a flat map

Testing

  • pnpm lint clean
  • pnpm check-types clean
  • pnpm test clean (362 pass; pre-existing eager-budget.test.ts
    syntax failure is unrelated to this PR)
  • Manual smoke-test of the affected feature
  • Platforms tested: Windows

Screenshots / GIFs

Split pane in action — two files side by side after Ctrl+D then clicking
a second file in the explorer.

split panels

Notes for reviewer

  • Terminal split behavior and all single-pane editor behavior are
    untouched. The diff in useTabs.ts looks large but each function's
    terminal branch is identical to before — only an editor branch was
    added after it.
  • The path? field on PaneNode leaf is optional and never set by
    terminal code, so existing terminal pane trees are unaffected.
  • Preview tabs (preview: true) are intentionally excluded from
    splitting (same guard as terminal's blocks flag).

Closes #533 (partial — editor splits only; cross-type tiling is out of scope)

Summary by CodeRabbit

  • New Features

    • Added split-pane support for editor tabs with independent per-pane focusing/closing, opening files into the focused pane, and go-to-line/navigation.
    • Editor tabs are now pane-backed, including per-pane Markdown raw/render switching.
    • Restored workspaces now preserve pane layouts and the active pane’s path.
  • Bug Fixes

    • Improved editor selection/search focus, shortcuts, dirty-state handling, and navigation across split panes.
    • Refined split rules for editor vs preview tabs and updated split-disable messaging when splitting isn’t possible.
  • Tests

    • Added/updated coverage for editor pane-tree splitting, leaf path updates, and editor pane serialization/hydration.

Extends the existing terminal pane tree system to editor tabs so users
can view different files side by side.

- Cmd/Ctrl+D / Cmd/Ctrl+Shift+D split editor pane right / down
- Cmd/Ctrl+[ / Cmd/Ctrl+] cycle focus between editor panes
- Cmd/Ctrl+W with multiple panes closes the active pane only
- Clicking a file in the explorer loads it into the focused split pane
  (falls back to new tab when the pane has unsaved changes)

No existing behavior changed. Single-pane editor tabs and all terminal
behavior are identical to before.

New unit tests cover split, close, and focus-after-close tree transforms
for editor pane trees (src/modules/tabs/lib/editorPanes.test.ts).
@SinanGncgl
SinanGncgl requested a review from crynta as a code owner July 13, 2026 11:19
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 15937685-dacb-44b8-8597-733b125ce85e

📥 Commits

Reviewing files that changed from the base of the PR and between 7d7585e and 8b46cf9.

📒 Files selected for processing (2)
  • src/app/App.tsx
  • src/modules/terminal/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/modules/terminal/index.ts
  • src/app/App.tsx

📝 Walkthrough

Walkthrough

Editor tabs now use pane trees with per-leaf paths, rendering, focus, dirty state, closing, splitting, file navigation, and editor command routing. Serialization, pane utilities, and workspace callback wiring were updated accordingly.

Changes

Editor pane multiplexing

Layer / File(s) Summary
Pane path model and persistence
src/modules/terminal/lib/panes.ts, src/modules/spaces/lib/serialize.ts, src/modules/tabs/lib/editorPanes.test.ts, src/modules/terminal/index.ts
Pane leaves gain paths and immutable path helpers; splitting propagates paths, restored editor tabs allocate matching leaf state, and pane behavior is tested.
Editor tab pane state
src/modules/tabs/lib/useTabs.ts, src/modules/terminal/lib/liveTerminals.test.ts, src/modules/command-palette/commands.ts, src/app/components/WorkspaceSurface.tsx
Editor tabs gain pane trees and active leaves, with path synchronization, splitting, focusing, closure, split availability, and lifecycle callback wiring.
Split editor rendering
src/modules/editor/EditorPaneTreeView.tsx, src/modules/editor/EditorStack.tsx
Editor pane trees render recursively through resizable panels with per-leaf handles, dirty state, focus and close callbacks, and Markdown view controls.
Application leaf routing
src/app/App.tsx
Editor commands, selection, file opening, goto-line navigation, dirty tracking, and pane actions now resolve against active editor leaves.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • crynta/terax-ai#982: Adds editor shortcut handlers that this change routes through leaf-specific editor handles.
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR only adds editor-tab pane splitting; #533 also asks for arbitrary panel types and reusable layouts, which are still missing. Implement cross-panel tiling, panel-type agnostic splits, and save/reuse layout support, or narrow the linked issue scope.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Conventional Commit format is used and the title accurately summarizes editor pane splitting for tabs.
Out of Scope Changes check ✅ Passed Changes stay focused on pane-tree support for editor and terminal tabs, related UI wiring, and tests; no unrelated subsystems were added.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/App.tsx`:
- Around line 558-573: Update the split-pane reuse condition in handleOpenFile
to require !pin alongside the existing editor, split, and clean-leaf checks.
Keep setLeafPath for preview opens only, allowing pinned or explicit opens to
continue through openFileTab.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 52d1be30-8655-40bd-9e2b-f04098f1db02

📥 Commits

Reviewing files that changed from the base of the PR and between fcff6c5 and f760559.

📒 Files selected for processing (12)
  • src/app/App.tsx
  • src/app/components/WorkspaceSurface.tsx
  • src/modules/command-palette/commands.ts
  • src/modules/editor/EditorPaneTreeView.tsx
  • src/modules/editor/EditorStack.tsx
  • src/modules/spaces/lib/serialize.test.ts
  • src/modules/spaces/lib/serialize.ts
  • src/modules/tabs/lib/editorPanes.test.ts
  • src/modules/tabs/lib/useTabs.ts
  • src/modules/terminal/index.ts
  • src/modules/terminal/lib/liveTerminals.test.ts
  • src/modules/terminal/lib/panes.ts

Comment thread src/app/App.tsx
AuricX and others added 6 commits July 20, 2026 01:28
Register file associations for common text/source/config types so Terax
appears in the OS "Open With" menu. Opening a file launches (or focuses)
the app, opens the file in an editor tab, and sets its parent folder as
the workspace.

- tauri.conf.json: bundle.fileAssociations (role Editor)
- lib.rs: accept a file launch arg (workspace = its parent); add
LaunchFile state + get_launch_file command; handle macOS
RunEvent::Opened (authorize parent, seed launch state, emit
"terax:open-file") for warm start and the cold-start race
- launchDir.ts: consumeLaunchFile()
- App.tsx: drain get_launch_file + listen "terax:open-file" -> open file

Register OS file associations so Terax appears in "Open With" for common
text/source/config files. Opening a file opens it in an editor tab and
makes its parent folder the workspace.

Today Terax only accepts a **directory** launch argument — you can't
hand
it a file from the file manager. Closes crynta#979.

- `tauri.conf.json`: `bundle.fileAssociations` (role `Editor`) for ~55
exts.
- `src-tauri/src/lib.rs`: launch-arg parsing now accepts a file
(workspace
= parent dir); added `LaunchFile` state + `get_launch_file` command;
added
a macOS `RunEvent::Opened` handler — GUI launches deliver Open-With
files
via the Apple open-files event, not argv — which authorizes the parent,
  seeds the drain-once launch state, and emits `terax:open-file` (covers
  warm start and the cold-start race).
- `src/lib/launchDir.ts`: `consumeLaunchFile()`.
- `src/app/App.tsx`: mount effect drains `get_launch_file` and listens
for
  `terax:open-file`, authorizes the parent, then opens the file.
  `openFileTab` dedupes by path, so double-delivery can't double-open.

- `pnpm check-types` clean, `pnpm lint` clean, `pnpm test` clean.
- `cargo clippy --all-targets --locked -- -D warnings` clean, `cargo
nextest run` clean.
- `pnpm tauri build`, launched via macOS Finder "Open With" and `open -a
<file>`:
  app launches, opens the file, no crash.

- [x] `pnpm lint` clean
- [x] `pnpm check-types` clean
- [x] `pnpm test` clean
- [x] Manual smoke-test of the affected feature
- [x] `cargo clippy --all-targets --locked -- -D warnings` clean
- [x] `cargo nextest run --locked` clean
- [x] Platforms tested: macOS

- The macOS `Opened` handler also seeds `LaunchDir` so the workspace
root
follows the file's folder on cold start; residual race if `Opened` fires
  after the webview polls is mitigated by the emit + listener.
- Linux/Windows **warm**-start ("Open With" into an already-running
instance) needs `tauri-plugin-single-instance` — not added here.
Cold-start
  via argv is wired but only manually tested on macOS.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

* **New Features**
* Added support for opening the app with a specific file (not just a
folder).
* Enhanced “Open With” handling on macOS to open the launched file
directly.
* Updated file associations so more text-based extensions open in Terax.
* **Bug Fixes**
* Improved warm-start and cold-start launch behavior to keep the correct
file active.
* Normalized Windows path separators for more reliable file-opening
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Tile Manager / Multi-Panel Workspace

3 participants