diff --git a/Sources/AppDelegate.swift b/Sources/AppDelegate.swift index cb6a838d..0787d814 100644 --- a/Sources/AppDelegate.swift +++ b/Sources/AppDelegate.swift @@ -417,11 +417,13 @@ enum TerminalDirectoryOpenTarget: String, CaseIterable { let homeDirectoryPath: String let fileExistsAtPath: (String) -> Bool let isExecutableFileAtPath: (String) -> Bool + let applicationPathForName: (String) -> String? static let live = DetectionEnvironment( homeDirectoryPath: FileManager.default.homeDirectoryForCurrentUser.path, fileExistsAtPath: { FileManager.default.fileExists(atPath: $0) }, - isExecutableFileAtPath: { FileManager.default.isExecutableFile(atPath: $0) } + isExecutableFileAtPath: { FileManager.default.isExecutableFile(atPath: $0) }, + applicationPathForName: { NSWorkspace.shared.fullPath(forApplication: $0) } ) } diff --git a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift index 71a728d2..96b4083b 100644 --- a/cmuxTests/CmuxWebViewKeyEquivalentTests.swift +++ b/cmuxTests/CmuxWebViewKeyEquivalentTests.swift @@ -7895,12 +7895,14 @@ final class FinderServicePathResolverTests: XCTestCase { final class TerminalDirectoryOpenTargetAvailabilityTests: XCTestCase { private func environment( existingPaths: Set, - homeDirectoryPath: String = "/Users/tester" + homeDirectoryPath: String = "/Users/tester", + applicationPathsByName: [String: String] = [:] ) -> TerminalDirectoryOpenTarget.DetectionEnvironment { TerminalDirectoryOpenTarget.DetectionEnvironment( homeDirectoryPath: homeDirectoryPath, fileExistsAtPath: { existingPaths.contains($0) }, - isExecutableFileAtPath: { existingPaths.contains($0) } + isExecutableFileAtPath: { existingPaths.contains($0) }, + applicationPathForName: { applicationPathsByName[$0] } ) } @@ -7939,9 +7941,10 @@ final class TerminalDirectoryOpenTargetAvailabilityTests: XCTestCase { XCTAssertFalse(availableTargets.contains(.vscode)) } - func testVSCodeRequiresCodeTunnelExecutable() { + func testVSCodeInlineRequiresCodeTunnelExecutable() { let env = environment(existingPaths: ["/Applications/Visual Studio Code.app"]) - XCTAssertFalse(TerminalDirectoryOpenTarget.vscode.isAvailable(in: env)) + XCTAssertTrue(TerminalDirectoryOpenTarget.vscode.isAvailable(in: env)) + XCTAssertFalse(TerminalDirectoryOpenTarget.vscodeInline.isAvailable(in: env)) } func testITerm2DetectsLegacyBundleName() { @@ -7954,6 +7957,35 @@ final class TerminalDirectoryOpenTargetAvailabilityTests: XCTestCase { XCTAssertTrue(TerminalDirectoryOpenTarget.tower.isAvailable(in: env)) } + func testAvailableTargetsFallbackToApplicationLookupForVSCodeAliasOutsideApplications() { + let vscodePath = "/Volumes/Tools/Code.app" + let env = environment( + existingPaths: [ + vscodePath, + "\(vscodePath)/Contents/Resources/app/bin/code-tunnel", + ], + applicationPathsByName: [ + "Code": vscodePath, + ] + ) + + let availableTargets = TerminalDirectoryOpenTarget.availableTargets(in: env) + XCTAssertTrue(availableTargets.contains(.vscode)) + XCTAssertTrue(availableTargets.contains(.vscodeInline)) + } + + func testTowerDetectedViaApplicationLookupOutsideApplications() { + let towerPath = "/Volumes/Setapp/Tower.app" + let env = environment( + existingPaths: [towerPath], + applicationPathsByName: [ + "Tower": towerPath, + ] + ) + + XCTAssertTrue(TerminalDirectoryOpenTarget.tower.isAvailable(in: env)) + } + func testCommandPaletteShortcutsExcludeGenericIDEEntry() { let targets = TerminalDirectoryOpenTarget.commandPaletteShortcutTargets XCTAssertFalse(targets.contains(where: { $0.commandPaletteTitle == "Open Current Directory in IDE" }))