Skip to content

Add file tree sidebar and code editor panel#601

Open
Shehryar wants to merge 6 commits intomanaflow-ai:mainfrom
Shehryar:feature/file-tree-code-editor
Open

Add file tree sidebar and code editor panel#601
Shehryar wants to merge 6 commits intomanaflow-ai:mainfrom
Shehryar:feature/file-tree-code-editor

Conversation

@Shehryar
Copy link

Summary

  • Adds a file tree browser to the sidebar, toggled with Cmd+Shift+E or persistent header buttons
  • Adds a split sidebar layout setting (tabs + file tree with draggable divider)
  • Adds a native code editor panel that opens files from the file tree
  • Tree-sitter syntax highlighting with Dracula theme (41 languages via CodeEditLanguages)
  • STTextView-based editor with auto-indentation and language-aware tab width

Details

File tree sidebar:

  • Scans active workspace directory with expand/collapse, hidden file toggle, refresh
  • Opens files in $EDITOR via terminal or in the built-in code editor panel
  • Mode toggle header persists across tab and file tree views
  • Keyboard shortcut (Cmd+Shift+E) configurable in settings

Split sidebar layout:

  • New setting in Sidebar preferences: Toggle (default) vs Split
  • Split mode shows tabs on top, file tree on bottom with a draggable horizontal divider

Code editor panel:

  • Opens as a new panel type alongside terminal and browser panels
  • Syntax highlighting via Neon + CodeEditLanguages (Tree-sitter)
  • Dracula theme with proper foreground colors for unmatched tokens
  • Save with Cmd+S, dirty indicator in tab

Test plan

  • Toggle file tree with Cmd+Shift+E in both directions
  • Browse and expand/collapse directories in file tree
  • Toggle hidden files visibility
  • Open a file from the file tree — verify editor panel opens with syntax highlighting
  • Edit and save a file (Cmd+S)
  • Switch sidebar layout setting between Toggle and Split
  • Verify split mode shows both tabs and file tree with working divider
  • Verify no regressions in tab sidebar behavior

🤖 Generated with Claude Code

Shehryar and others added 6 commits February 26, 2026 17:26
Adds a file tree browser to the sidebar that can be toggled with the tab
list via persistent header buttons or Cmd+Shift+E. The file tree scans the
active workspace directory, supports expand/collapse, hidden file toggle,
refresh, and opens files in $EDITOR via the terminal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a "Sidebar File Tree" setting (Settings > App) with two modes:
- Toggle (default): tabs and file tree are mutually exclusive (Cmd+Shift+E)
- Split: tabs on top, file tree on bottom with a draggable horizontal divider

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Opens files from the file tree sidebar as in-app editor tabs instead of
sending $EDITOR to the terminal. Plain text editing with monospaced
NSTextView, Cmd+S save, dirty state tracking, and close confirmation
for unsaved changes. Deduplicates tabs by file path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire up Neon + CodeEditLanguages for incremental, viewport-aware
syntax highlighting across 41 languages. Uses Dracula color spec,
async highlighting setup with per-language caching, and plain-text
paste override for the rich text view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Swap out the custom NSTextView/Neon/CodeEditLanguages code editor for
STTextView (TextKit 2) with Plugin-Neon syntax highlighting and
Plugin-TextFormation for bracket pairing and smart indentation.

- STTextView handles line numbers, current line highlight, scroll natively
- Plugin-Neon provides Tree-sitter syntax highlighting (20 languages, Dracula theme)
- Plugin-TextFormation provides auto-close brackets/quotes, skip-over,
  delete-matching, newline-between-pairs, and pattern-based indentation
- Removes unused CodeEditorTextEditing.swift and LineNumberRulerView.swift
- Adds editor-tab-width config key (default 4, clamped 1-16)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on persistence

- Add triggerFlash() to CodeEditorPanel (required by updated Panel protocol)
- Add .codeEditor cases to session snapshot/restore switches
- Update vendor/bonsplit submodule to match upstream

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Feb 27, 2026

@Shehryar is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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

@lawrencecchen
Copy link
Contributor

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db85d157dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +12 to +14
Task {
let nodes = await scanDirectory(path)
self.rootNodes = nodes

Choose a reason for hiding this comment

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

P2 Badge Guard async directory scans against out-of-order completion

loadDirectory launches an untracked async scan and always assigns its result to rootNodes, so if users switch workspaces/directories quickly, an older scan can finish after a newer one and overwrite the tree with stale entries (while rootPath now points elsewhere). This causes the sidebar to show files from the wrong directory and can open the wrong file when clicked; add cancellation or verify the scanned path still matches the current root before publishing.

Useful? React with 👍 / 👎.

Comment on lines +477 to +483
Button("Toggle File Tree") {
if sidebarContentModeState.mode == .fileTree {
sidebarContentModeState.mode = .tabs
} else {
sidebarContentModeState.mode = .fileTree
if !sidebarState.isVisible {
sidebarState.toggle()

Choose a reason for hiding this comment

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

P2 Badge Route file-tree menu action through active window context

This menu command mutates the app-level sidebarContentModeState/sidebarState directly, unlike the adjacent "Toggle Sidebar" action that first targets the active main window via AppDelegate. In multi-window use, invoking "Toggle File Tree" from a non-primary window will toggle the primary window's state instead of the focused window, producing inconsistent behavior between menu action and per-window shortcut handling.

Useful? React with 👍 / 👎.

@lawrencecchen
Copy link
Contributor

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db85d157dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +12 to +14
Task {
let nodes = await scanDirectory(path)
self.rootNodes = nodes

Choose a reason for hiding this comment

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

P1 Badge Guard async directory loads against stale results

loadDirectory starts a new Task and always assigns its scan result to rootNodes, but there is no generation/cancellation check against the latest rootPath. If the user switches tabs/workspaces quickly (or triggers another load before the first scan finishes), an older task can complete last and overwrite the tree with the wrong directory contents.

Useful? React with 👍 / 👎.

Comment on lines +147 to +149
let _ = self.findAndUpdate(in: &current, id: nodeId) { n in
n.children = children
}

Choose a reason for hiding this comment

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

P2 Badge Reapply expanded state when lazy-loading refreshed children

refresh() collects expanded IDs recursively, but in restoreExpandedState the async lazy-load path only does n.children = children and never reapplies expandedIds to the newly loaded subtree. This means nested folders that were expanded before refresh are collapsed afterward, despite the method claiming to preserve expanded state.

Useful? React with 👍 / 👎.

Comment on lines +477 to +481
Button("Toggle File Tree") {
if sidebarContentModeState.mode == .fileTree {
sidebarContentModeState.mode = .tabs
} else {
sidebarContentModeState.mode = .fileTree

Choose a reason for hiding this comment

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

P2 Badge Route Toggle File Tree menu action to active window

This command mutates the app-level sidebarContentModeState/sidebarState captured by cmuxApp, while additional windows get their own SidebarContentModeState in AppDelegate.createMainWindow. In multi-window use, invoking Toggle File Tree from a non-primary window can toggle the wrong window���s sidebar state.

Useful? React with 👍 / 👎.

AlexBoudreaux added a commit to AlexBoudreaux/cmux that referenced this pull request Mar 1, 2026
Port file tree sidebar from PR manaflow-ai#601 (credit @Shehryar) and add
cmd-click to inject file paths into the active terminal pane.

- File tree sidebar toggled with Cmd+Shift+E
- Toggle or split layout with workspace tabs
- Cmd-click any file/folder to insert its shell-escaped path into terminal
- Regular click expands/collapses dirs, selects files
- Right-click context menu (copy path, reveal in Finder, open, insert path)
- Lazy directory loading, hidden files toggle, manual refresh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AlexBoudreaux added a commit to AlexBoudreaux/cmux that referenced this pull request Mar 2, 2026
Port file tree sidebar concept from PR manaflow-ai#601 (credit @Shehryar) and add
cmd-click to inject file paths into the active terminal pane.

- File tree sidebar toggled with Cmd+E or titlebar folder button
- Cmd-click any file/folder to insert shell-escaped path into terminal
- Regular click to select files, expand/collapse folders
- Right-click context menu (Copy Path, Reveal in Finder, Open in Default App)
- FSEvents file watching for automatic tree refresh
- Hidden files shown by default
- Lazy directory loading with preserved expand state on refresh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants