Repository navigation
Add Open Folder in VS Code (Inline) menu item and command palette entry #2409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5661,6 +5661,86 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent | |
| } | ||
| } | ||
|
|
||
| @discardableResult | ||
| func openDirectoryInInlineVSCode( | ||
| _ directoryURL: URL, | ||
| tabManager preferredTabManager: TabManager? = nil | ||
| ) -> Bool { | ||
| guard let vscodeApplicationURL = TerminalDirectoryOpenTarget.vscodeInline.applicationURL() else { | ||
| return false | ||
| } | ||
|
|
||
| let targetTabManager = preferredTabManager | ||
| ?? preferredMainWindowContextForWorkspaceCreation(debugSource: "inlineVSCode.open.target")?.tabManager | ||
| guard let targetTabManager else { | ||
| return false | ||
| } | ||
|
|
||
| let targetWorkspaceId = targetTabManager.selectedWorkspace?.id | ||
| ?? targetTabManager.tabs.first?.id | ||
| ?? targetTabManager.addWorkspace(select: true).id | ||
| let normalizedDirectoryURL = directoryURL.standardizedFileURL | ||
|
|
||
| VSCodeServeWebController.shared.ensureServeWebURL(vscodeApplicationURL: vscodeApplicationURL) { serveWebURL in | ||
| guard let serveWebURL, | ||
| let openFolderURL = VSCodeServeWebURLBuilder.openFolderURL( | ||
| baseWebUIURL: serveWebURL, | ||
| directoryPath: normalizedDirectoryURL.path | ||
| ) else { | ||
| NSSound.beep() | ||
| return | ||
| } | ||
|
|
||
| guard targetTabManager.openBrowser( | ||
| inWorkspace: targetWorkspaceId, | ||
| url: openFolderURL, | ||
| preferSplitRight: true | ||
| ) != nil else { | ||
|
Comment on lines
+5679
to
+5698
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Recompute workspace ID inside the async callback to avoid stale-target failures.
Suggested fix- let targetWorkspaceId = targetTabManager.selectedWorkspace?.id
- ?? targetTabManager.tabs.first?.id
- ?? targetTabManager.addWorkspace(select: true).id
let normalizedDirectoryURL = directoryURL.standardizedFileURL
VSCodeServeWebController.shared.ensureServeWebURL(vscodeApplicationURL: vscodeApplicationURL) { serveWebURL in
guard let serveWebURL,
let openFolderURL = VSCodeServeWebURLBuilder.openFolderURL(
baseWebUIURL: serveWebURL,
directoryPath: normalizedDirectoryURL.path
) else {
NSSound.beep()
return
}
+ let targetWorkspaceId = targetTabManager.selectedWorkspace?.id
+ ?? targetTabManager.tabs.first?.id
+ ?? targetTabManager.addWorkspace(select: true).id
guard targetTabManager.openBrowser(
inWorkspace: targetWorkspaceId,
url: openFolderURL,
preferSplitRight: true
) != nil else {🤖 Prompt for AI Agents |
||
| NSSound.beep() | ||
| return | ||
| } | ||
| } | ||
|
|
||
| return true | ||
|
Comment on lines
+5664
to
+5704
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The refactored As a result, when a workspace already has multiple panes, the right-click context-menu "Open in VS Code (Inline)" action will now reuse the top-right pane (loading a new surface there) rather than always appending a new split adjacent to the focused terminal. The test plan checks whether the context action still works, but doesn't explicitly verify the split position. It's worth confirming the new reuse-pane behaviour is intentional for the context-menu case (it may well be — fewer unwanted splits is arguably better UX). |
||
| } | ||
|
|
||
| func showOpenFolderInInlineVSCodePanel(tabManager preferredTabManager: TabManager? = nil) { | ||
| guard TerminalDirectoryOpenTarget.vscodeInline.isAvailable() else { | ||
| NSSound.beep() | ||
| return | ||
| } | ||
|
|
||
| let targetTabManager = preferredTabManager | ||
| ?? preferredMainWindowContextForWorkspaceCreation(debugSource: "inlineVSCode.panel.target")?.tabManager | ||
| guard let targetTabManager else { | ||
| NSSound.beep() | ||
| return | ||
| } | ||
|
|
||
| let panel = NSOpenPanel() | ||
| panel.canChooseFiles = false | ||
| panel.canChooseDirectories = true | ||
| panel.allowsMultipleSelection = false | ||
| panel.title = String( | ||
| localized: "menu.file.openFolderInVSCodeInline.panelTitle", | ||
| defaultValue: "Open Folder in VS Code (Inline)" | ||
| ) | ||
| panel.prompt = String( | ||
| localized: "menu.file.openFolderInVSCodeInline.panelPrompt", | ||
| defaultValue: "Open in VS Code" | ||
| ) | ||
| if let cwd = targetTabManager.selectedWorkspace?.currentDirectory, | ||
| !cwd.isEmpty { | ||
| panel.directoryURL = URL(fileURLWithPath: cwd) | ||
| } | ||
|
|
||
| if panel.runModal() == .OK, | ||
| let url = panel.url, | ||
| !openDirectoryInInlineVSCode(url, tabManager: targetTabManager) { | ||
| NSSound.beep() | ||
| } | ||
| } | ||
|
|
||
| @objc func openWindow( | ||
| _ pasteboard: NSPasteboard, | ||
| userData: String?, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The third branch of the
??chain eagerly callsaddWorkspace(select: true)as a side-effect of what appears to be a simple ID lookup. IfselectedWorkspaceis nil ANDtabs.firstis nil (e.g., the user has closed all tabs in the window between the panel's appear and the OK click), a brand-new, empty workspace is created just to serve as the target for the VS Code browser — which can be confusing and unexpected.Consider guarding against this case instead:
If there are genuinely no workspaces, returning
false(and lettingshowOpenFolderInInlineVSCodePanelemit a beep) is safer than silently creating one.