Skip to content

fix(openFolder): default NSOpenPanel to focused workspace directory - #2070

Closed
BillionClaw wants to merge 1 commit into
manaflow-ai:mainfrom
BillionClaw:clawoss/fix/cmux-2010-open-folder-default-directory
Closed

BillionClaw wants to merge 1 commit into
manaflow-ai:mainfrom
BillionClaw:clawoss/fix/cmux-2010-open-folder-default-directory

Conversation

@BillionClaw

@BillionClaw BillionClaw commented Mar 25, 2026 •

Copy link
Copy Markdown
Contributor

NSOpenPanel was created without a directoryURL, causing the ⌘O file picker to always open at ~/Documents instead of the focused workspace's working directory.

Fix by setting panel.directoryURL to the selected tab's currentDirectory before running the modal in both the menu bar File → Open Folder action and the command palette openFolder handler.

Fixes #2010.


Summary by cubic

Default the Open Folder (NSOpenPanel) to the focused workspace’s working directory (menu File → Open Folder and command palette), instead of always opening at ~/Documents; falls back to the system default when no workspace is open. Fixes #2010.

Written for commit 0a17725. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes
    • The "Open Folder" dialog now intelligently pre-selects your current working directory from the active tab, eliminating the need to manually navigate to commonly used folders. This streamlines your workflow and provides a more intuitive folder selection experience.

NSOpenPanel was created without a directoryURL, causing the file picker
to always open at ~/Documents instead of the focused workspace's working
directory.

Fix by setting panel.directoryURL to the selected tab's currentDirectory
before running the modal, falling back to the system default when no
workspace is open.
@vercel

vercel Bot commented Mar 25, 2026

Copy link
Copy Markdown

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

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Mar 25, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The "Open Folder" command handler in ContentView and cmuxApp now initializes NSOpenPanel with the currently selected tab's directory before presenting the file picker, instead of relying on macOS default behavior that defaulted to the Documents folder.

Changes

Cohort / File(s) Summary
Open Folder Command Initialization
Sources/ContentView.swift, Sources/cmuxApp.swift
Both files now seed the NSOpenPanel's initial directoryURL with the active tab's currentDirectory (when available) when handling the palette.openFolder command, providing contextual directory selection instead of defaulting to ~/Documents.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • PR #685: Modifies ContentView's open-folder command handling with VS Code inline routing and helpers, affecting the same command handler flow.
  • PR #656: Adds the palette.openFolder command and NSOpenPanel behavior; this PR complements it by setting the panel's initial directory context from the active tab.

Poem

🐰 A hop, a skip, a folder's way,
No more lost in Documents' bay,
The tab now guides with gentle care,
To directories nested anywhere! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description explains what changed and why, but lacks testing details and a demo video as specified in the template. Add details about how the change was tested locally and include a demo video showing the file picker opening at the workspace directory.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: setting NSOpenPanel to default to the focused workspace directory instead of the default location.
Linked Issues check ✅ Passed The pull request directly addresses issue #2010 by setting NSOpenPanel's directoryURL to the selected tab's currentDirectory, matching the expected behavior of opening the file picker at the workspace directory.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the NSOpenPanel directory default in both the menu File → Open Folder and command palette handlers, with no unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@greptile-apps

greptile-apps Bot commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes NSOpenPanel always opening at ~/Documents by setting panel.directoryURL to the focused workspace's currentDirectory before running the modal. The fix is applied consistently in both the command-palette openFolder handler (ContentView.swift) and the File → Open Folder menu button (cmuxApp.swift).

  • The if let optional binding correctly handles the no-tab-selected edge case — the panel falls back to its default directory when there's no selected tab.
  • Both call sites use URL(fileURLWithPath: currentDir) without specifying isDirectory: true; while this works in practice (NSOpenPanel resolves the path), it's a minor best-practice to include isDirectory: true explicitly.
  • No other unrelated NSOpenPanel() sites were modified, which is appropriate — this change is scoped to the two "Open Folder" entry points described in the bug report.

Confidence Score: 5/5

  • Safe to merge — minimal, targeted fix with no logic risk.
  • The change is a two-line addition in two well-isolated locations, guarded by an optional binding. There are no new failure modes, no thread-safety concerns (both sites execute on the main thread), and the fallback (no-op when selectedTab is nil) is handled correctly. The only note is a best-practice suggestion to pass isDirectory: true, which does not affect correctness.
  • No files require special attention.

Important Files Changed

Filename Overview
Sources/ContentView.swift Adds panel.directoryURL assignment in the command-palette openFolder handler using the selected tab's currentDirectory. Logic is correct; minor style improvement available (isDirectory: true).
Sources/cmuxApp.swift Adds panel.directoryURL assignment in the File → Open Folder menu button. Mirrors the ContentView.swift fix and is equally correct; same minor style note applies.

Sequence Diagram

sequenceDiagram
    participant User
    participant EntryPoint as "⌘O / File → Open Folder"
    participant TabManager
    participant NSOpenPanel

    User->>EntryPoint: triggers Open Folder
    EntryPoint->>TabManager: selectedTab?.currentDirectory
    alt tab exists
        TabManager-->>EntryPoint: "/path/to/workspace"
        EntryPoint->>NSOpenPanel: directoryURL = URL(fileURLWithPath:)
    else no tab selected
        TabManager-->>EntryPoint: nil
        Note over EntryPoint,NSOpenPanel: directoryURL left unset (default)
    end
    EntryPoint->>NSOpenPanel: runModal()
    NSOpenPanel-->>User: panel opens at workspace directory
    User->>NSOpenPanel: selects folder → OK
    NSOpenPanel-->>EntryPoint: url.path
    EntryPoint->>TabManager: addWorkspace(workingDirectory:)
Loading

Reviews (1): Last reviewed commit: "fix(openFolder): default NSOpenPanel to ..." | Re-trigger Greptile

Comment thread Sources/ContentView.swift
panel.title = String(localized: "panel.openFolder.title", defaultValue: "Open Folder")
panel.prompt = String(localized: "panel.openFolder.prompt", defaultValue: "Open")
if let currentDir = tabManager.selectedTab?.currentDirectory {
panel.directoryURL = URL(fileURLWithPath: currentDir)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Prefer isDirectory: true for directory URLs

URL(fileURLWithPath:) without an isDirectory argument will inspect the filesystem (or fall back to a heuristic based on the trailing slash) to decide whether to treat the path as a directory. Since currentDirectory is always a directory path, pass isDirectory: true explicitly to guarantee a well-formed directory URL is handed to NSOpenPanel.

Suggested change
panel.directoryURL = URL(fileURLWithPath: currentDir)
panel.directoryURL = URL(fileURLWithPath: currentDir, isDirectory: true)

Comment thread Sources/cmuxApp.swift
panel.title = String(localized: "menu.file.openFolder.panelTitle", defaultValue: "Open Folder")
panel.prompt = String(localized: "menu.file.openFolder.panelPrompt", defaultValue: "Open")
if let currentDir = activeTabManager.selectedTab?.currentDirectory {
panel.directoryURL = URL(fileURLWithPath: currentDir)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Prefer isDirectory: true for directory URLs

Same note as ContentView.swift: use URL(fileURLWithPath: currentDir, isDirectory: true) to produce a canonical directory URL without a filesystem round-trip.

Suggested change
panel.directoryURL = URL(fileURLWithPath: currentDir)
panel.directoryURL = URL(fileURLWithPath: currentDir, isDirectory: true)

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/cmuxApp.swift`:
- Around line 596-598: The code assumes
activeTabManager.selectedTab?.currentDirectory is a valid local folder; instead
verify it before assigning panel.directoryURL: get the currentDirectory string
from activeTabManager.selectedTab?.currentDirectory, check with FileManager
(e.g., FileManager.default.fileExists(atPath:isDirectory:)) that the path exists
and is a directory, and only then set panel.directoryURL = URL(fileURLWithPath:
currentDirectory); if the check fails, do not set panel.directoryURL so the
system default is used. This touches the currentDirectory usage in the code near
activeTabManager.selectedTab?.currentDirectory and the panel.directoryURL
assignment.

In `@Sources/ContentView.swift`:
- Around line 5979-5981: Replace the direct use of
tabManager.selectedTab?.currentDirectory with the focused panel's cwd (e.g.,
check tabManager.focusedTab?.focusedPanel?.currentDirectory first, then fall
back to tabManager.selectedTab?.currentDirectory), and validate the path before
assigning to panel.directoryURL: ensure the string is non-empty and
FileManager.default.fileExists(atPath:isDirectory:) returns true for a
directory; only then set panel.directoryURL = URL(fileURLWithPath: validPath) so
the system default fallback remains intact when the path is missing or invalid.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 260e850e-4558-430d-8f05-4793f90cdf06

📥 Commits

Reviewing files that changed from the base of the PR and between 441118b and 0a17725.

📒 Files selected for processing (2)
  • Sources/ContentView.swift
  • Sources/cmuxApp.swift

Comment thread Sources/cmuxApp.swift
Comment on lines +596 to +598
if let currentDir = activeTabManager.selectedTab?.currentDirectory {
panel.directoryURL = URL(fileURLWithPath: currentDir)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Validate currentDirectory before assigning panel.directoryURL.

On Line 597, currentDirectory is treated as a guaranteed local folder path. In practice this value can be stale/remote/non-existent, which can make the picker open in an unintended location instead of using the system default fallback.

Suggested fix
-                    if let currentDir = activeTabManager.selectedTab?.currentDirectory {
-                        panel.directoryURL = URL(fileURLWithPath: currentDir)
-                    }
+                    if let currentDir = activeTabManager.selectedTab?.currentDirectory?
+                        .trimmingCharacters(in: .whitespacesAndNewlines),
+                       !currentDir.isEmpty {
+                        let candidateURL = URL(fileURLWithPath: currentDir).standardizedFileURL
+                        var isDirectory: ObjCBool = false
+                        if FileManager.default.fileExists(atPath: candidateURL.path, isDirectory: &isDirectory),
+                           isDirectory.boolValue {
+                            panel.directoryURL = candidateURL
+                        }
+                    }

Based on learnings from Sources/Workspace.swift and Sources/TerminalView.swift, currentDirectory is a raw string updated from terminal-reported paths and is not guaranteed to be a valid local directory.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/cmuxApp.swift` around lines 596 - 598, The code assumes
activeTabManager.selectedTab?.currentDirectory is a valid local folder; instead
verify it before assigning panel.directoryURL: get the currentDirectory string
from activeTabManager.selectedTab?.currentDirectory, check with FileManager
(e.g., FileManager.default.fileExists(atPath:isDirectory:)) that the path exists
and is a directory, and only then set panel.directoryURL = URL(fileURLWithPath:
currentDirectory); if the check fails, do not set panel.directoryURL so the
system default is used. This touches the currentDirectory usage in the code near
activeTabManager.selectedTab?.currentDirectory and the panel.directoryURL
assignment.

Comment thread Sources/ContentView.swift
Comment on lines +5979 to +5981
if let currentDir = tabManager.selectedTab?.currentDirectory {
panel.directoryURL = URL(fileURLWithPath: currentDir)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use focused directory + validate path before assigning directoryURL.

Line 5979 currently uses selectedTab?.currentDirectory directly. That can miss the focused panel’s cwd and can also assign invalid/empty paths, which weakens the intended “fallback to system default” behavior.

Suggested fix
-                if let currentDir = tabManager.selectedTab?.currentDirectory {
-                    panel.directoryURL = URL(fileURLWithPath: currentDir)
-                }
+                if let directory = focusedDirectory {
+                    let trimmed = directory.trimmingCharacters(in: .whitespacesAndNewlines)
+                    var isDirectory: ObjCBool = false
+                    if !trimmed.isEmpty,
+                       FileManager.default.fileExists(atPath: trimmed, isDirectory: &isDirectory),
+                       isDirectory.boolValue {
+                        panel.directoryURL = URL(fileURLWithPath: trimmed, isDirectory: true)
+                    }
+                }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/ContentView.swift` around lines 5979 - 5981, Replace the direct use
of tabManager.selectedTab?.currentDirectory with the focused panel's cwd (e.g.,
check tabManager.focusedTab?.focusedPanel?.currentDirectory first, then fall
back to tabManager.selectedTab?.currentDirectory), and validate the path before
assigning to panel.directoryURL: ensure the string is non-empty and
FileManager.default.fileExists(atPath:isDirectory:) returns true for a
directory; only then set panel.directoryURL = URL(fileURLWithPath: validPath) so
the system default fallback remains intact when the path is missing or invalid.

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Sources/ContentView.swift">

<violation number="1" location="Sources/ContentView.swift:5980">
P2: Open-folder panel start directory is derived from an unvalidated path, so empty/invalid values can open the picker in an unexpected location.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread Sources/ContentView.swift
panel.title = String(localized: "panel.openFolder.title", defaultValue: "Open Folder")
panel.prompt = String(localized: "panel.openFolder.prompt", defaultValue: "Open")
if let currentDir = tabManager.selectedTab?.currentDirectory {
panel.directoryURL = URL(fileURLWithPath: currentDir)

@cubic-dev-ai cubic-dev-ai Bot Mar 25, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Open-folder panel start directory is derived from an unvalidated path, so empty/invalid values can open the picker in an unexpected location.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Sources/ContentView.swift, line 5980:

<comment>Open-folder panel start directory is derived from an unvalidated path, so empty/invalid values can open the picker in an unexpected location.</comment>

<file context>
@@ -5976,6 +5976,9 @@ struct ContentView: View {
                 panel.title = String(localized: "panel.openFolder.title", defaultValue: "Open Folder")
                 panel.prompt = String(localized: "panel.openFolder.prompt", defaultValue: "Open")
+                if let currentDir = tabManager.selectedTab?.currentDirectory {
+                    panel.directoryURL = URL(fileURLWithPath: currentDir)
+                }
                 if panel.runModal() == .OK, let url = panel.url {
</file context>
Fix with Cubic

@lawrencecchen

Copy link
Copy Markdown
Contributor

Thanks for the contribution! This has been addressed by #2034 which was just merged.

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.

⌘O opens macOS Documents folder instead of intended action

2 participants