diff --git a/Sources/ContentView.swift b/Sources/ContentView.swift index e9a7e04d..b5418cff 100644 --- a/Sources/ContentView.swift +++ b/Sources/ContentView.swift @@ -6016,6 +6016,8 @@ private struct TabItemView: View { @AppStorage("sidebarShowBranchDirectory") private var sidebarShowBranchDirectory = true @AppStorage("sidebarShowGitBranchIcon") private var sidebarShowGitBranchIcon = false @AppStorage("sidebarShowPullRequest") private var sidebarShowPullRequest = true + @AppStorage(BrowserLinkOpenSettings.openSidebarPullRequestLinksInCmuxBrowserKey) + private var openSidebarPullRequestLinksInCmuxBrowser = BrowserLinkOpenSettings.defaultOpenSidebarPullRequestLinksInCmuxBrowser @AppStorage("sidebarShowPorts") private var sidebarShowPorts = true @AppStorage("sidebarShowLog") private var sidebarShowLog = true @AppStorage("sidebarShowProgress") private var sidebarShowProgress = true @@ -6322,8 +6324,7 @@ private struct TabItemView: View { VStack(alignment: .leading, spacing: 1) { ForEach(pullRequestDisplays) { pullRequest in Button(action: { - updateSelection() - NSWorkspace.shared.open(pullRequest.url) + openPullRequestLink(pullRequest.url) }) { HStack(spacing: 4) { PullRequestStatusIcon( @@ -6939,6 +6940,17 @@ private struct TabItemView: View { isActive ? .white.opacity(0.75) : .secondary } + private func openPullRequestLink(_ url: URL) { + updateSelection() + if openSidebarPullRequestLinksInCmuxBrowser { + if tabManager.openBrowser(url: url, insertAtEnd: true) == nil { + NSWorkspace.shared.open(url) + } + return + } + NSWorkspace.shared.open(url) + } + private func pullRequestStatusLabel(_ status: SidebarPullRequestStatus) -> String { switch status { case .open: return "open" diff --git a/Sources/Panels/BrowserPanel.swift b/Sources/Panels/BrowserPanel.swift index 71f297bb..07f1fd45 100644 --- a/Sources/Panels/BrowserPanel.swift +++ b/Sources/Panels/BrowserPanel.swift @@ -127,6 +127,9 @@ enum BrowserLinkOpenSettings { static let openTerminalLinksInCmuxBrowserKey = "browserOpenTerminalLinksInCmuxBrowser" static let defaultOpenTerminalLinksInCmuxBrowser: Bool = true + static let openSidebarPullRequestLinksInCmuxBrowserKey = "browserOpenSidebarPullRequestLinksInCmuxBrowser" + static let defaultOpenSidebarPullRequestLinksInCmuxBrowser: Bool = true + static let interceptTerminalOpenCommandInCmuxBrowserKey = "browserInterceptTerminalOpenCommandInCmuxBrowser" static let defaultInterceptTerminalOpenCommandInCmuxBrowser: Bool = true @@ -140,6 +143,13 @@ enum BrowserLinkOpenSettings { return defaults.bool(forKey: openTerminalLinksInCmuxBrowserKey) } + static func openSidebarPullRequestLinksInCmuxBrowser(defaults: UserDefaults = .standard) -> Bool { + if defaults.object(forKey: openSidebarPullRequestLinksInCmuxBrowserKey) == nil { + return defaultOpenSidebarPullRequestLinksInCmuxBrowser + } + return defaults.bool(forKey: openSidebarPullRequestLinksInCmuxBrowserKey) + } + static func interceptTerminalOpenCommandInCmuxBrowser(defaults: UserDefaults = .standard) -> Bool { if defaults.object(forKey: interceptTerminalOpenCommandInCmuxBrowserKey) != nil { return defaults.bool(forKey: interceptTerminalOpenCommandInCmuxBrowserKey) diff --git a/Sources/cmuxApp.swift b/Sources/cmuxApp.swift index 0f193ba1..63dbc3b0 100644 --- a/Sources/cmuxApp.swift +++ b/Sources/cmuxApp.swift @@ -2631,6 +2631,8 @@ struct SettingsView: View { private var sidebarActiveTabIndicatorStyle = SidebarActiveTabIndicatorSettings.defaultStyle.rawValue @AppStorage("sidebarShowBranchDirectory") private var sidebarShowBranchDirectory = true @AppStorage("sidebarShowPullRequest") private var sidebarShowPullRequest = true + @AppStorage(BrowserLinkOpenSettings.openSidebarPullRequestLinksInCmuxBrowserKey) + private var openSidebarPullRequestLinksInCmuxBrowser = BrowserLinkOpenSettings.defaultOpenSidebarPullRequestLinksInCmuxBrowser @AppStorage("sidebarShowPorts") private var sidebarShowPorts = true @AppStorage("sidebarShowLog") private var sidebarShowLog = true @AppStorage("sidebarShowProgress") private var sidebarShowProgress = true @@ -2877,6 +2879,19 @@ struct SettingsView: View { SettingsCardDivider() + SettingsCardRow( + "Open Sidebar PR Links in cmux Browser", + subtitle: openSidebarPullRequestLinksInCmuxBrowser + ? "Clicks open inside cmux browser." + : "Clicks open in your default browser." + ) { + Toggle("", isOn: $openSidebarPullRequestLinksInCmuxBrowser) + .labelsHidden() + .controlSize(.small) + } + + SettingsCardDivider() + SettingsCardRow( "Show Listening Ports in Sidebar", subtitle: "Display detected listening ports for the active workspace." @@ -3460,6 +3475,7 @@ struct SettingsView: View { sidebarActiveTabIndicatorStyle = SidebarActiveTabIndicatorSettings.defaultStyle.rawValue sidebarShowBranchDirectory = true sidebarShowPullRequest = true + openSidebarPullRequestLinksInCmuxBrowser = BrowserLinkOpenSettings.defaultOpenSidebarPullRequestLinksInCmuxBrowser sidebarShowPorts = true sidebarShowLog = true sidebarShowProgress = true diff --git a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift index d84c20a6..59bcab74 100644 --- a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift +++ b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift @@ -6352,6 +6352,18 @@ final class BrowserLinkOpenSettingsTests: XCTestCase { XCTAssertTrue(BrowserLinkOpenSettings.openTerminalLinksInCmuxBrowser(defaults: defaults)) } + func testSidebarPullRequestLinksDefaultToCmuxBrowser() { + XCTAssertTrue(BrowserLinkOpenSettings.openSidebarPullRequestLinksInCmuxBrowser(defaults: defaults)) + } + + func testSidebarPullRequestLinksPreferenceUsesStoredValue() { + defaults.set(false, forKey: BrowserLinkOpenSettings.openSidebarPullRequestLinksInCmuxBrowserKey) + XCTAssertFalse(BrowserLinkOpenSettings.openSidebarPullRequestLinksInCmuxBrowser(defaults: defaults)) + + defaults.set(true, forKey: BrowserLinkOpenSettings.openSidebarPullRequestLinksInCmuxBrowserKey) + XCTAssertTrue(BrowserLinkOpenSettings.openSidebarPullRequestLinksInCmuxBrowser(defaults: defaults)) + } + func testOpenCommandInterceptionDefaultsToCmuxBrowser() { XCTAssertTrue(BrowserLinkOpenSettings.interceptTerminalOpenCommandInCmuxBrowser(defaults: defaults)) }