Add "Open Folder in VS Code (Inline)" via menu and command palette
Adds a File menu item and command palette entry to pick a local folder and open it in an inline VS Code browser panel. Extracts the inline VS Code open logic from ContentView into a reusable AppDelegate method so both the right-click context action and the new open-panel flow share the same code path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
112358ed01
commit
1918264ae0
4 changed files with 200 additions and 29 deletions
|
|
@ -19547,6 +19547,40 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"command.openFolderInVSCodeInline.subtitle": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "VS Code Inline"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "VS Code インライン"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"command.openFolderInVSCodeInline.title": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Open Folder in VS Code (Inline)…"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "フォルダを VS Code で開く(インライン)…"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"command.openSettings.subtitle": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
|
|
@ -38571,6 +38605,57 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"menu.file.openFolderInVSCodeInline": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Open Folder in VS Code (Inline)…"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "フォルダを VS Code で開く(インライン)…"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu.file.openFolderInVSCodeInline.panelPrompt": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Open in VS Code"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "VS Code で開く"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu.file.openFolderInVSCodeInline.panelTitle": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
"en": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "Open Folder in VS Code (Inline)"
|
||||
}
|
||||
},
|
||||
"ja": {
|
||||
"stringUnit": {
|
||||
"state": "translated",
|
||||
"value": "フォルダを VS Code で開く(インライン)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu.file.reopenClosedBrowserPanel": {
|
||||
"extractionState": "manual",
|
||||
"localizations": {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
NSSound.beep()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
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?,
|
||||
|
|
|
|||
|
|
@ -5550,6 +5550,25 @@ struct ContentView: View {
|
|||
keywords: ["open", "folder", "repository", "project", "directory"]
|
||||
)
|
||||
)
|
||||
contributions.append(
|
||||
CommandPaletteCommandContribution(
|
||||
commandId: "palette.openFolderInVSCodeInline",
|
||||
title: constant(
|
||||
String(
|
||||
localized: "command.openFolderInVSCodeInline.title",
|
||||
defaultValue: "Open Folder in VS Code (Inline)…"
|
||||
)
|
||||
),
|
||||
subtitle: constant(
|
||||
String(
|
||||
localized: "command.openFolderInVSCodeInline.subtitle",
|
||||
defaultValue: "VS Code Inline"
|
||||
)
|
||||
),
|
||||
keywords: ["open", "folder", "directory", "project", "vs", "code", "inline", "editor", "browser"],
|
||||
when: { _ in TerminalDirectoryOpenTarget.vscodeInline.isAvailable() }
|
||||
)
|
||||
)
|
||||
contributions.append(
|
||||
CommandPaletteCommandContribution(
|
||||
commandId: "palette.newTerminalTab",
|
||||
|
|
@ -6244,6 +6263,11 @@ struct ContentView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
registry.register(commandId: "palette.openFolderInVSCodeInline") {
|
||||
DispatchQueue.main.async {
|
||||
AppDelegate.shared?.showOpenFolderInInlineVSCodePanel(tabManager: tabManager)
|
||||
}
|
||||
}
|
||||
registry.register(commandId: "palette.newWindow") {
|
||||
AppDelegate.shared?.openNewMainWindow(nil)
|
||||
}
|
||||
|
|
@ -7642,35 +7666,7 @@ struct ContentView: View {
|
|||
}
|
||||
|
||||
private func openFocusedDirectoryInInlineVSCode(_ directoryURL: URL) -> Bool {
|
||||
guard let vscodeApplicationURL = TerminalDirectoryOpenTarget.vscodeInline.applicationURL(),
|
||||
let workspace = tabManager.selectedWorkspace,
|
||||
let sourcePanelId = workspace.focusedPanelId else {
|
||||
return false
|
||||
}
|
||||
let sourceTabId = workspace.id
|
||||
let tabManager = tabManager
|
||||
VSCodeServeWebController.shared.ensureServeWebURL(vscodeApplicationURL: vscodeApplicationURL) { serveWebURL in
|
||||
guard let serveWebURL,
|
||||
let openFolderURL = VSCodeServeWebURLBuilder.openFolderURL(
|
||||
baseWebUIURL: serveWebURL,
|
||||
directoryPath: directoryURL.path
|
||||
) else {
|
||||
NSSound.beep()
|
||||
return
|
||||
}
|
||||
guard tabManager.newBrowserSplit(
|
||||
tabId: sourceTabId,
|
||||
fromPanelId: sourcePanelId,
|
||||
orientation: SplitDirection.right.orientation,
|
||||
insertFirst: SplitDirection.right.insertFirst,
|
||||
url: openFolderURL,
|
||||
focus: true
|
||||
) != nil else {
|
||||
NSSound.beep()
|
||||
return
|
||||
}
|
||||
}
|
||||
return true
|
||||
AppDelegate.shared?.openDirectoryInInlineVSCode(directoryURL, tabManager: tabManager) ?? false
|
||||
}
|
||||
|
||||
private func stopInlineVSCodeServeWeb() {
|
||||
|
|
|
|||
|
|
@ -588,6 +588,16 @@ struct cmuxApp: App {
|
|||
splitCommandButton(title: String(localized: "menu.file.openFolder", defaultValue: "Open Folder…"), shortcut: openFolderMenuShortcut) {
|
||||
AppDelegate.shared?.showOpenFolderPanel()
|
||||
}
|
||||
|
||||
Button(
|
||||
String(
|
||||
localized: "menu.file.openFolderInVSCodeInline",
|
||||
defaultValue: "Open Folder in VS Code (Inline)…"
|
||||
)
|
||||
) {
|
||||
AppDelegate.shared?.showOpenFolderInInlineVSCodePanel()
|
||||
}
|
||||
.disabled(!TerminalDirectoryOpenTarget.vscodeInline.isAvailable())
|
||||
}
|
||||
|
||||
// Close tab/workspace
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue