Skip to content

fix(openFolder): set NSOpenPanel directoryURL to focused pane's working directory - #2019

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

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

Conversation

@BillionClaw

@BillionClaw BillionClaw commented Mar 23, 2026 •

Copy link
Copy Markdown
Contributor

Before: ⌘O always opened the file picker at ~/Documents (NSOpenPanel default).
After: ⌘O now opens the picker at the focused pane's current working directory when available, falling back to ~/Documents otherwise.\n\nRoot cause: Both the menu bar and command palette Open Folder handlers created NSOpenPanel without setting directoryURL, so macOS defaulted to ~/Documents.\n\nFixes: #2010


Summary by cubic

⌘O now opens the folder picker at the focused pane’s working directory, falling back to ~/Documents when no directory is available. Applies to both the menu bar and command palette.

  • Bug Fixes
    • Set NSOpenPanel.directoryURL using the focused pane’s working directory in both ContentView and cmuxApp handlers.

Written for commit 1403491. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes
    • The "Open Folder…" command now remembers the last directory you accessed, streamlining folder selection for frequently used locations.

…ng directory

Before: ⌘O always opened the file picker at ~/Documents (NSOpenPanel default).
After: ⌘O now opens the picker at the focused pane's current working directory
when available, falling back to ~/Documents otherwise.

Fixes: manaflow-ai#2010
@vercel

vercel Bot commented Mar 23, 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 23, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The "Open Folder…" command across both ContentView.swift and cmuxApp.swift now pre-configures the NSOpenPanel's directoryURL to default to the currently selected workspace's focused panel's saved directory when available. Workspace creation calls are qualified with self for explicit reference.

Changes

Cohort / File(s) Summary
Open Folder Pre-configuration
Sources/ContentView.swift, Sources/cmuxApp.swift
Pre-configure NSOpenPanel's directoryURL using the focused panel's saved directory from the workspace instead of defaulting to macOS Documents folder. Workspace creation calls qualified with self.tabManager and self.activeTabManager.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~4 minutes

Possibly related PRs

Poem

🐰 No more journeys to the Documents deep,
The folder picker finds the path to keep—
Focused panels guide the way with cheer,
To the workspace's home, forever near! 📁✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

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.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: updating NSOpenPanel's directoryURL to use the focused pane's working directory, which is the primary fix implemented in both ContentView.swift and cmuxApp.swift.
Description check ✅ Passed The description is well-structured with clear context (before/after behavior, root cause) and explicitly references the linked issue #2010, though it lacks the specific sections from the repository template (Testing, Demo Video, Checklist).
Linked Issues check ✅ Passed The changes directly address issue #2010 by setting NSOpenPanel's directoryURL to the focused pane's working directory in both ContentView.swift and cmuxApp.swift handlers, with appropriate fallback behavior.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the Open Folder file picker behavior in two files; no unrelated modifications or refactoring detected outside the stated objective.

✏️ 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.

@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.

No issues found across 2 files

@greptile-apps

greptile-apps Bot commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes ⌘O ("Open Folder") in both the menu bar and command palette so that NSOpenPanel opens at the focused pane's current working directory instead of always defaulting to ~/Documents. The fix is minimal and correct — panelDirectories is the right source of truth, and the focusedPanelId lookup is properly guarded for nil and empty string.

  • Both handlers (ContentView.swift command palette, cmuxApp.swift menu bar) receive the symmetric fix.
  • URL(fileURLWithPath: preferredDir) is used to construct the directoryURL. This works in the common case but may silently fall back to the default when the stored path no longer exists on disk, because URL(fileURLWithPath:) consults the file system to set hasDirectoryPath. Using URL(fileURLWithPath: preferredDir, isDirectory: true) would be more robust.
  • No regression test is included; given the project's test-quality policy discouraging fake behavioral tests, this is acceptable here — the change is a two-line UI behavioural fix with no practical unit-testable seam.

Confidence Score: 5/5

  • Safe to merge — the fix is correct and narrowly scoped; the isDirectory concern is a minor robustness improvement that doesn't affect the happy path.
  • Both call sites are symmetric, the guard for nil/empty is correct, and the fallback to ~/Documents is preserved. The only note is the URL construction without isDirectory: true, which only matters when the working directory has been deleted — an edge case where silent fallback to ~/Documents is still acceptable behaviour.
  • No files require special attention.

Important Files Changed

Filename Overview
Sources/ContentView.swift Command-palette "Open Folder" handler updated to set NSOpenPanel.directoryURL from the focused pane's working directory; one minor: URL should be constructed with isDirectory: true for correctness when the directory no longer exists on disk.
Sources/cmuxApp.swift Menu-bar "Open Folder" handler receives the same directoryURL fix; same isDirectory: true concern applies on line 597.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["User triggers ⌘O\n(menu bar OR command palette)"] --> B["Create NSOpenPanel"]
    B --> C{"selectedWorkspace\n.focusedPanelId\n!= nil?"}
    C -- No --> E["NSOpenPanel defaults\nto ~/Documents"]
    C -- Yes --> D{"panelDirectories\n[focusedPanelId]\nnon-empty?"}
    D -- No --> E
    D -- Yes --> F["panel.directoryURL =\nURL(fileURLWithPath: preferredDir)"]
    F --> G["panel.runModal()"]
    E --> G
    G -- ".OK" --> H["tabManager.addWorkspace\n(workingDirectory: url.path)"]
    G -- "cancelled" --> I["No-op"]
Loading

Reviews (1): Last reviewed commit: "fix(openFolder): set NSOpenPanel directo..." | 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 preferredDir = self.tabManager.selectedWorkspace?.focusedPanelId.flatMap({ self.tabManager.selectedWorkspace?.panelDirectories[$0] }), !preferredDir.isEmpty {
panel.directoryURL = URL(fileURLWithPath: preferredDir)

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 Use isDirectory: true when constructing directory URL

URL(fileURLWithPath:) without isDirectory: true consults the file system to infer whether the path is a file or directory. If the working directory stored in panelDirectories has since been deleted (e.g. the user rm -rf'd a temp dir in the terminal), the stat will fail and the resulting URL will have hasDirectoryPath == false. NSOpenPanel ignores a directoryURL that isn't a directory URL, silently falling back to ~/Documents — the exact behavior this PR is trying to fix.

Explicitly passing isDirectory: true makes the intent unambiguous and ensures the URL is formed correctly regardless of whether the path still exists on disk:

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

The same issue exists in Sources/cmuxApp.swift:597.

@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 current logic sets panel.directoryURL only when a
focused panel's panelDirectories entry exists, so when that lookup is missing it
falls back to the global default; update the code around
activeTabManager.selectedWorkspace?.focusedPanelId and panelDirectories to first
try the focused panel directory, and if that is nil or empty fall back to the
workspace-level directory (e.g.,
activeTabManager.selectedWorkspace?.currentDirectory) before finally defaulting
to ~/Documents; ensure you check for non-empty strings and set
panel.directoryURL = URL(fileURLWithPath: <chosenPath>) using the workspace
currentDirectory when available.

In `@Sources/ContentView.swift`:
- Around line 5978-5980: When setting panel.directoryURL in ContentView, prefer
the focused panel directory but fall back to the workspace-level directory
before letting NSOpenPanel use its default: update the logic around
tabManager.selectedWorkspace?.focusedPanelId and panelDirectories so that if
preferredDir is nil or empty you attempt to read the workspace directory (e.g.
tabManager.selectedWorkspace?.directory or similar workspace-level path
property) and set panel.directoryURL = URL(fileURLWithPath: workspaceDir) when
present; only if both focused panel and workspace directory are absent should
you leave the panel to use NSOpenPanel's default.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 39a7f169-c6a3-44b3-8722-f43d43ccafb9

📥 Commits

Reviewing files that changed from the base of the PR and between b5fb304 and 1403491.

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

Comment thread Sources/cmuxApp.swift
Comment on lines +596 to +598
if let preferredDir = self.activeTabManager.selectedWorkspace?.focusedPanelId.flatMap({ self.activeTabManager.selectedWorkspace?.panelDirectories[$0] }), !preferredDir.isEmpty {
panel.directoryURL = URL(fileURLWithPath: preferredDir)
}

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 | 🟠 Major

Add workspace-level fallback before defaulting to Documents

Line 596 only uses focusedPanelId -> panelDirectories. If that lookup is missing (e.g., fresh workspace/no OSC7 update yet), the picker still opens at the default location instead of a workspace-contextual path. Please fall back to workspace-level directory (e.g., currentDirectory) before ~/Documents.

💡 Suggested patch
-                    if let preferredDir = self.activeTabManager.selectedWorkspace?.focusedPanelId.flatMap({ self.activeTabManager.selectedWorkspace?.panelDirectories[$0] }), !preferredDir.isEmpty {
-                        panel.directoryURL = URL(fileURLWithPath: preferredDir)
-                    }
+                    let workspace = self.activeTabManager.selectedWorkspace
+                    let focusedPaneDir = workspace.flatMap { ws in
+                        ws.focusedPanelId.flatMap { ws.panelDirectories[$0] }
+                    }
+                    let startDir = (
+                        focusedPaneDir
+                        ?? workspace?.currentDirectory
+                        ?? NSString(string: "~/Documents").expandingTildeInPath
+                    ).trimmingCharacters(in: .whitespacesAndNewlines)
+                    if !startDir.isEmpty {
+                        panel.directoryURL = URL(fileURLWithPath: startDir)
+                    }
🤖 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 current logic sets
panel.directoryURL only when a focused panel's panelDirectories entry exists, so
when that lookup is missing it falls back to the global default; update the code
around activeTabManager.selectedWorkspace?.focusedPanelId and panelDirectories
to first try the focused panel directory, and if that is nil or empty fall back
to the workspace-level directory (e.g.,
activeTabManager.selectedWorkspace?.currentDirectory) before finally defaulting
to ~/Documents; ensure you check for non-empty strings and set
panel.directoryURL = URL(fileURLWithPath: <chosenPath>) using the workspace
currentDirectory when available.

Comment thread Sources/ContentView.swift
Comment on lines +5978 to +5980
if let preferredDir = self.tabManager.selectedWorkspace?.focusedPanelId.flatMap({ self.tabManager.selectedWorkspace?.panelDirectories[$0] }), !preferredDir.isEmpty {
panel.directoryURL = URL(fileURLWithPath: preferredDir)
}

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 | 🟠 Major

Use workspace directory fallback before defaulting to NSOpenPanel’s default location.

Line 5978 only uses the focused panel directory. When that value is absent, this still falls back to default picker behavior instead of the workspace directory context, so the issue can reproduce.

💡 Proposed fix
-                if let preferredDir = self.tabManager.selectedWorkspace?.focusedPanelId.flatMap({ self.tabManager.selectedWorkspace?.panelDirectories[$0] }), !preferredDir.isEmpty {
-                    panel.directoryURL = URL(fileURLWithPath: preferredDir)
-                }
+                if let workspace = self.tabManager.selectedWorkspace {
+                    let focusedDir = workspace.focusedPanelId
+                        .flatMap { workspace.panelDirectories[$0] }?
+                        .trimmingCharacters(in: .whitespacesAndNewlines)
+                    let workspaceDir = workspace.currentDirectory.trimmingCharacters(in: .whitespacesAndNewlines)
+
+                    if let focusedDir, !focusedDir.isEmpty, FileManager.default.fileExists(atPath: focusedDir) {
+                        panel.directoryURL = URL(fileURLWithPath: focusedDir, isDirectory: true)
+                    } else if !workspaceDir.isEmpty, FileManager.default.fileExists(atPath: workspaceDir) {
+                        panel.directoryURL = URL(fileURLWithPath: workspaceDir, isDirectory: true)
+                    } else {
+                        panel.directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
+                    }
+                }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if let preferredDir = self.tabManager.selectedWorkspace?.focusedPanelId.flatMap({ self.tabManager.selectedWorkspace?.panelDirectories[$0] }), !preferredDir.isEmpty {
panel.directoryURL = URL(fileURLWithPath: preferredDir)
}
if let workspace = self.tabManager.selectedWorkspace {
let focusedDir = workspace.focusedPanelId
.flatMap { workspace.panelDirectories[$0] }?
.trimmingCharacters(in: .whitespacesAndNewlines)
let workspaceDir = workspace.currentDirectory.trimmingCharacters(in: .whitespacesAndNewlines)
if let focusedDir, !focusedDir.isEmpty, FileManager.default.fileExists(atPath: focusedDir) {
panel.directoryURL = URL(fileURLWithPath: focusedDir, isDirectory: true)
} else if !workspaceDir.isEmpty, FileManager.default.fileExists(atPath: workspaceDir) {
panel.directoryURL = URL(fileURLWithPath: workspaceDir, isDirectory: true)
} else {
panel.directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/ContentView.swift` around lines 5978 - 5980, When setting
panel.directoryURL in ContentView, prefer the focused panel directory but fall
back to the workspace-level directory before letting NSOpenPanel use its
default: update the logic around tabManager.selectedWorkspace?.focusedPanelId
and panelDirectories so that if preferredDir is nil or empty you attempt to read
the workspace directory (e.g. tabManager.selectedWorkspace?.directory or similar
workspace-level path property) and set panel.directoryURL = URL(fileURLWithPath:
workspaceDir) when present; only if both focused panel and workspace directory
are absent should you leave the panel to use NSOpenPanel's default.

@BillionClaw

Copy link
Copy Markdown
Contributor Author

This is BillionClaw. Happy to discuss the approach or make adjustments to the fix.

@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.

2 participants