diff --git a/Copilot for Xcode/Assets.xcassets/copilotIcon.imageset/Contents.json b/Copilot for Xcode/Assets.xcassets/copilotIcon.imageset/Contents.json deleted file mode 100644 index ae075ee..0000000 --- a/Copilot for Xcode/Assets.xcassets/copilotIcon.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "filename" : "CopilotforXcode-Icon@256w_1x.png", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Copilot for Xcode/Assets.xcassets/copilotIcon.imageset/CopilotforXcode-Icon@256w_1x.png b/Copilot for Xcode/Assets.xcassets/copilotIcon.imageset/CopilotforXcode-Icon@256w_1x.png deleted file mode 100644 index 7674f66..0000000 Binary files a/Copilot for Xcode/Assets.xcassets/copilotIcon.imageset/CopilotforXcode-Icon@256w_1x.png and /dev/null differ diff --git a/Core/Sources/HostApp/GeneralView.swift b/Core/Sources/HostApp/GeneralView.swift index 0353f06..44d63be 100644 --- a/Core/Sources/HostApp/GeneralView.swift +++ b/Core/Sources/HostApp/GeneralView.swift @@ -67,7 +67,7 @@ struct AppInfoView: View { var body: some View { VStack(alignment: .leading) { HStack(alignment: .center, spacing: 16) { - Image("copilotIcon") + Image(nsImage: NSImage(named: "AppIcon") ?? NSImage()) .resizable() .frame(width: 110, height: 110) VStack(alignment: .leading) { @@ -168,21 +168,20 @@ struct GeneralSettingsView: View { .padding(8) Divider() - HStack { - VStack(alignment: .leading) { - Text(StringConstants.extensionPermission) - .font(.body) - Text(""" - Check for GitHub Copilot in Xcode's Editor menu. \ - Restart Xcode if greyed out. - """) - .font(.footnote) + Link(destination: URL(string: "x-apple.systempreferences:com.apple.ExtensionsPreferences")!) { + HStack { + VStack(alignment: .leading) { + Text(StringConstants.extensionPermission) + .font(.body) + Text(""" + Check for GitHub Copilot in Xcode's Editor menu. \ + Restart Xcode if greyed out. + """) + .font(.footnote) + } + Spacer() + Image(systemName: "chevron.right") } - Spacer() - Image(systemName: "chevron.right") - } - .onTapGesture { - shouldPresentExtensionPermissionAlert = true } .foregroundStyle(.primary) .padding(.horizontal, 8) diff --git a/Core/Sources/SuggestionWidget/ChatPanelWindow.swift b/Core/Sources/SuggestionWidget/ChatPanelWindow.swift index 7d189aa..3f1b772 100644 --- a/Core/Sources/SuggestionWidget/ChatPanelWindow.swift +++ b/Core/Sources/SuggestionWidget/ChatPanelWindow.swift @@ -44,7 +44,6 @@ final class ChatPanelWindow: NSWindow { .transient, .fullScreenPrimary, .fullScreenAllowsTiling, - .canJoinAllSpaces ] hasShadow = true contentView = NSHostingView( diff --git a/Server/package-lock.json b/Server/package-lock.json index bd41e39..b3acac4 100644 --- a/Server/package-lock.json +++ b/Server/package-lock.json @@ -8,13 +8,13 @@ "name": "@github/copilot-xcode", "version": "0.0.1", "dependencies": { - "@github/copilot-language-server": "^1.237.0" + "@github/copilot-language-server": "^1.238.0" } }, "node_modules/@github/copilot-language-server": { - "version": "1.237.0", - "resolved": "https://registry.npmjs.org/@github/copilot-language-server/-/copilot-language-server-1.237.0.tgz", - "integrity": "sha512-2LvMSFNs6smYoC5lndXWF57ara3iFa2j1/T+nrzHaFYPIDlcp/wq0N6TMXNGpeeYVz2EqLQ/1Vw52drOHGMztQ==", + "version": "1.238.0", + "resolved": "https://registry.npmjs.org/@github/copilot-language-server/-/copilot-language-server-1.238.0.tgz", + "integrity": "sha512-pkNiTUc4o1KKwlFvSAnG97Mz6PSAhG7LTXwzGetkYr4vZySwZ1ne2SU3Cfqn+ndTlw/I03W0MuG3DjENk/GFiQ==", "bin": { "copilot-language-server": "dist/language-server.js" } diff --git a/Server/package.json b/Server/package.json index b556127..c36ed20 100644 --- a/Server/package.json +++ b/Server/package.json @@ -4,6 +4,6 @@ "description": "Package for downloading @github/copilot-language-server", "private": true, "dependencies": { - "@github/copilot-language-server": "^1.237.0" + "@github/copilot-language-server": "^1.238.0" } } diff --git a/Tool/Sources/GitHubCopilotService/LanguageServer/GitHubCopilotService.swift b/Tool/Sources/GitHubCopilotService/LanguageServer/GitHubCopilotService.swift index 806fd90..4b947b9 100644 --- a/Tool/Sources/GitHubCopilotService/LanguageServer/GitHubCopilotService.swift +++ b/Tool/Sources/GitHubCopilotService/LanguageServer/GitHubCopilotService.swift @@ -227,7 +227,8 @@ public class GitHubCopilotBaseService { in: .userDomainMask ).first?.appendingPathComponent( Bundle.main - .object(forInfoDictionaryKey: "APPLICATION_SUPPORT_FOLDER") as! String + .object(forInfoDictionaryKey: "APPLICATION_SUPPORT_FOLDER") as? String + ?? "com.github.CopilotForXcode" ) else { throw CancellationError() } diff --git a/Tool/Sources/SharedUIComponents/AsyncCodeBlock.swift b/Tool/Sources/SharedUIComponents/AsyncCodeBlock.swift index f5bf5a1..250f198 100644 --- a/Tool/Sources/SharedUIComponents/AsyncCodeBlock.swift +++ b/Tool/Sources/SharedUIComponents/AsyncCodeBlock.swift @@ -154,6 +154,15 @@ public struct AsyncCodeBlock: View { .fixedSize() } + @ViewBuilder + func lineBackgroundShape(_ multiLine: Bool) -> some View { + let color = currentLineBackgroundColor ?? backgroundColor + switch multiLine { + case true: HalfCapsule().fill(color) + case false: Rectangle().fill(color) + } + } + @ScaledMetric var iconPadding: CGFloat = 9.0 @ScaledMetric var iconSpacing: CGFloat = 6.0 @ScaledMetric var optionPadding: CGFloat = 0.5 @@ -199,9 +208,7 @@ public struct AsyncCodeBlock: View { } } .frame(height: lineHeight) - .background( - HalfCapsule().fill(currentLineBackgroundColor ?? backgroundColor) - ) + .background(lineBackgroundShape(lines.count > 1)) .padding(.leading, firstLineIndent) .onHover { hovering in guard hovering != isHovering else { return } diff --git a/Tool/Sources/SharedUIComponents/CopilotIntroSheet.swift b/Tool/Sources/SharedUIComponents/CopilotIntroSheet.swift index a6008b9..9192e83 100644 --- a/Tool/Sources/SharedUIComponents/CopilotIntroSheet.swift +++ b/Tool/Sources/SharedUIComponents/CopilotIntroSheet.swift @@ -25,7 +25,7 @@ struct CopilotIntroItem: View { image .resizable() .renderingMode(.template) - .foregroundColor(Color(red: 0.0353, green: 0.4118, blue: 0.8549)) + .foregroundColor(.blue) .scaledToFit() .frame(width: 28, height: 28) VStack(alignment: .leading, spacing: 5) { @@ -39,6 +39,66 @@ struct CopilotIntroItem: View { } } +struct CopilotIntroContent: View { + let hideIntro: Binding + let continueAction: () -> Void + + var body: some View { + VStack { + let appImage = if let nsImage = NSImage(named: "AppIcon") { + Image(nsImage: nsImage) + } else { + Image(systemName: "app") + } + appImage + .resizable() + .scaledToFit() + .frame(width: 64, height: 64) + .padding(.bottom, 24) + Text("Welcome to Copilot for Xcode!") + .font(.title.bold()) + .padding(.bottom, 38) + + VStack(alignment: .leading, spacing: 20) { + CopilotIntroItem( + imageName: "CopilotLogo", + heading: "In-line Code Suggestions", + text: "Copilot's code suggestions and text completion now available in Xcode. Press Tab ⇥ to accept a suggestion." + ) + + CopilotIntroItem( + systemImage: "option", + heading: "Full Suggestion", + text: "Press Option ⌥ key to display the full suggestion. Only the first line of suggestions are shown inline." + ) + + CopilotIntroItem( + imageName: "GitHubMark", + heading: "GitHub Context", + text: "Copilot utilizes project context to deliver smarter code suggestions relevant to your unique codebase." + ) + } + .padding(.bottom, 64) + + VStack(spacing: 8) { + Button(action: continueAction) { + Text("Continue") + .padding(.horizontal, 80) + .padding(.vertical, 6) + } + .buttonStyle(.borderedProminent) + + Toggle("Don't show again", isOn: hideIntro) + .toggleStyle(.checkbox) + } + } + .padding(.horizontal, 56) + .padding(.top, 48) + .padding(.bottom, 16) + .frame(width: 560) + } +} + public struct CopilotIntroSheet: View { let content: Content let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "" @@ -48,58 +108,13 @@ public struct CopilotIntroSheet: View { public var body: some View { content.sheet(isPresented: $isPresented) { - VStack { - Image(nsImage: NSImage(named: "AppIcon") ?? NSImage()) - .resizable() - .scaledToFit() - .frame(width: 64, height: 64) - .padding(.bottom, 24) - Text("Welcome to Copilot for Xcode!") - .font(.title) - .padding(.bottom, 45) - - VStack(alignment: .leading, spacing: 25) { - CopilotIntroItem( - imageName: "CopilotLogo", - heading: "In-line Code Suggestions", - text: "Copilot's code suggestions and text completion now available in Xcode. Just press Tab ⇥ to accept a suggestion." - ) - - CopilotIntroItem( - systemImage: "option", - heading: "Full Suggestion", - text: "Press Option ⌥ key to display the full suggestion. Only the first line of suggestions are shown inline." - ) - - CopilotIntroItem( - imageName: "GitHubMark", - heading: "GitHub Context", - text: "Copilot utilizes GitHub and project context to deliver smarter completions and personalized code suggestions relevant to your unique codebase." - ) - } - - Spacer() - - VStack(spacing: 8) { - Button(action: { isPresented = false }) { - Text("Continue") - .padding(.horizontal, 80) - .padding(.vertical, 6) - } - .buttonStyle(.borderedProminent) - - Toggle("Don't show again", isOn: $hideIntro) - .toggleStyle(.checkbox) - } + CopilotIntroContent(hideIntro: $hideIntro) { + isPresented = false } - .padding(EdgeInsets(top: 50, leading: 50, bottom: 16, trailing: 50)) - .frame(width: 560, height: 528) } .task { - let neverShown = introLastShownVersion.isEmpty - isPresented = neverShown || !hideIntro - if isPresented { - hideIntro = neverShown ? true : hideIntro // default to hidden on first time + if hideIntro == false { + isPresented = true introLastShownVersion = appVersion } } @@ -111,3 +126,10 @@ public extension View { CopilotIntroSheet(content: self) } } + + +// MARK: - Preview +@available(macOS 14.0, *) +#Preview(traits: .sizeThatFitsLayout) { + CopilotIntroContent(hideIntro: .constant(false)) { } +}