Skip to content

Commit 33b6371

Browse files
committed
Pre-release 0.28.95
1 parent 8353a90 commit 33b6371

32 files changed

+424
-125
lines changed

Copilot for Xcode.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
3ABBEA2D2C8BA00B00C61D61 /* copilot-language-server in Resources */ = {isa = PBXBuildFile; fileRef = 3ABBEA282C8B9FE100C61D61 /* copilot-language-server */; };
1414
424ACA212CA4697200FA20F2 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 424ACA202CA4697200FA20F2 /* Credits.rtf */; };
1515
427C63282C6E868B000E557C /* OpenSettingsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 427C63272C6E868B000E557C /* OpenSettingsCommand.swift */; };
16-
42888D512C66B10100DEF835 /* AuthStatusChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42888D502C66B10100DEF835 /* AuthStatusChecker.swift */; };
1716
5EC511E32C90CE7400632BAB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C8189B1D2938973000C9DCDA /* Assets.xcassets */; };
1817
5EC511E42C90CE9800632BAB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C8189B1D2938973000C9DCDA /* Assets.xcassets */; };
1918
5EC511E52C90CFD600632BAB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C861E6142994F6080056CB02 /* Assets.xcassets */; };
@@ -192,7 +191,6 @@
192191
3ABBEA2A2C8BA00300C61D61 /* copilot-language-server-arm64 */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = "copilot-language-server-arm64"; path = "Server/node_modules/@github/copilot-language-server/native/darwin-arm64/copilot-language-server-arm64"; sourceTree = SOURCE_ROOT; };
193192
424ACA202CA4697200FA20F2 /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
194193
427C63272C6E868B000E557C /* OpenSettingsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSettingsCommand.swift; sourceTree = "<group>"; };
195-
42888D502C66B10100DEF835 /* AuthStatusChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthStatusChecker.swift; sourceTree = "<group>"; };
196194
C8009BFE2941C551007AA7E8 /* ToggleRealtimeSuggestionsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleRealtimeSuggestionsCommand.swift; sourceTree = "<group>"; };
197195
C8009C022941C576007AA7E8 /* SyncTextSettingsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTextSettingsCommand.swift; sourceTree = "<group>"; };
198196
C800DBB0294C624D00B04CAC /* PrefetchSuggestionsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefetchSuggestionsCommand.swift; sourceTree = "<group>"; };
@@ -425,7 +423,6 @@
425423
C81291D52994FE6900196E12 /* Main.storyboard */,
426424
C861E6142994F6080056CB02 /* Assets.xcassets */,
427425
C861E6192994F6080056CB02 /* ExtensionService.entitlements */,
428-
42888D502C66B10100DEF835 /* AuthStatusChecker.swift */,
429426
);
430427
path = ExtensionService;
431428
sourceTree = "<group>";
@@ -769,7 +766,6 @@
769766
C89E75C32A46FB32000DD64F /* AppDelegate+Menu.swift in Sources */,
770767
C8738B712BE4F8B700609E7F /* XPCController.swift in Sources */,
771768
C861E6202994F63A0056CB02 /* ServiceDelegate.swift in Sources */,
772-
42888D512C66B10100DEF835 /* AuthStatusChecker.swift in Sources */,
773769
C861E6112994F6070056CB02 /* AppDelegate.swift in Sources */,
774770
);
775771
runOnlyForDeploymentPostprocessing = 0;

Core/Sources/HostApp/GitHubCopilotViewModel.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import Foundation
12
import GitHubCopilotService
23
import ComposableArchitecture
4+
import Status
35
import SwiftUI
46

57
struct SignInResponse {
@@ -79,6 +81,7 @@ class GitHubCopilotViewModel: ObservableObject {
7981
do {
8082
let service = try getGitHubCopilotAuthService()
8183
status = try await service.signOut()
84+
broadcastStatusChange()
8285
} catch {
8386
toast(error.localizedDescription, .error)
8487
}
@@ -118,6 +121,7 @@ class GitHubCopilotViewModel: ObservableObject {
118121
waitingForSignIn = false
119122
self.username = username
120123
self.status = status
124+
broadcastStatusChange()
121125
} catch let error as GitHubCopilotError {
122126
if case .languageServerError(.timeout) = error {
123127
// TODO figure out how to extend the default timeout on a Chime LSP request
@@ -131,4 +135,11 @@ class GitHubCopilotViewModel: ObservableObject {
131135
}
132136
}
133137
}
138+
139+
func broadcastStatusChange() {
140+
DistributedNotificationCenter.default().post(
141+
name: .authStatusDidChange,
142+
object: nil
143+
)
144+
}
134145
}

Core/Sources/Service/Service.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ public final class Service {
3232
let globalShortcutManager: GlobalShortcutManager
3333
let keyBindingManager: KeyBindingManager
3434
let xcodeThemeController: XcodeThemeController = .init()
35-
public var markAsProcessing: (Bool) -> Void = { _ in }
3635

3736
@Dependency(\.toast) var toast
3837
var cancellable = Set<AnyCancellable>()

Core/Sources/Service/SuggestionPresenter/PresentInWindowSuggestionPresenter.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ struct PresentInWindowSuggestionPresenter {
3030
Task { @MainActor in
3131
let controller = Service.shared.guiController.widgetController
3232
controller.markAsProcessing(isProcessing)
33-
Service.shared.markAsProcessing(isProcessing)
3433
}
3534
}
3635

Docs/downloaded-from-internet.png

-247 KB
Binary file not shown.

ExtensionService/AppDelegate+Menu.swift

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ extension AppDelegate {
2727
.init("toggleIgnoreLanguageMenuItem")
2828
}
2929

30-
fileprivate var copilotStatusMenuItemIdentifier: NSUserInterfaceItemIdentifier {
31-
.init("copilotStatusMenuItem")
32-
}
33-
3430
@MainActor
3531
@objc func buildStatusBarMenu() {
3632
let statusBar = NSStatusBar.system
@@ -52,7 +48,7 @@ extension AppDelegate {
5248
keyEquivalent: ""
5349
)
5450

55-
let openCopilotForXcode = NSMenuItem(
51+
let openCopilotForXcodeItem = NSMenuItem(
5652
title: "Open \(hostAppName) Settings",
5753
action: #selector(openCopilotForXcode),
5854
keyEquivalent: ""
@@ -97,12 +93,11 @@ extension AppDelegate {
9793
)
9894
toggleIgnoreLanguage.identifier = toggleIgnoreLanguageMenuItemIdentifier;
9995

100-
let copilotStatus = NSMenuItem(
96+
authMenuItem = NSMenuItem(
10197
title: "Copilot Connection: Checking...",
102-
action: nil,
98+
action: #selector(openCopilotForXcode),
10399
keyEquivalent: ""
104100
)
105-
copilotStatus.identifier = copilotStatusMenuItemIdentifier
106101

107102
let openDocs = NSMenuItem(
108103
title: "View Copilot Documentation...",
@@ -116,13 +111,13 @@ extension AppDelegate {
116111
keyEquivalent: ""
117112
)
118113

119-
statusBarMenu.addItem(openCopilotForXcode)
114+
statusBarMenu.addItem(openCopilotForXcodeItem)
120115
statusBarMenu.addItem(.separator())
121116
statusBarMenu.addItem(checkForUpdate)
122117
statusBarMenu.addItem(toggleCompletions)
123118
statusBarMenu.addItem(toggleIgnoreLanguage)
124119
statusBarMenu.addItem(.separator())
125-
statusBarMenu.addItem(copilotStatus)
120+
statusBarMenu.addItem(authMenuItem)
126121
statusBarMenu.addItem(statusMenuItem)
127122
statusBarMenu.addItem(.separator())
128123
statusBarMenu.addItem(openDocs)
@@ -165,14 +160,6 @@ extension AppDelegate: NSMenuDelegate {
165160
}
166161
}
167162

168-
statusChecker.updateStatusInBackground(notify: { (status: String, isOk: Bool) in
169-
if let statusItem = menu.items.first(where: { item in
170-
item.identifier == self.copilotStatusMenuItemIdentifier
171-
}) {
172-
statusItem.title = "Copilot Connection: \(isOk ? "Connected" : status)"
173-
}
174-
})
175-
176163
case xcodeInspectorDebugMenuIdentifier:
177164
let inspector = XcodeInspector.shared
178165
menu.items.removeAll()

ExtensionService/AppDelegate.swift

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,20 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
3232
let service = Service.shared
3333
var statusBarItem: NSStatusItem!
3434
var statusMenuItem: NSMenuItem!
35+
var authMenuItem: NSMenuItem!
3536
var xpcController: XPCController?
3637
let updateChecker =
3738
UpdateChecker(
3839
hostBundle: Bundle(url: locateHostBundleURL(url: Bundle.main.bundleURL)),
3940
checkerDelegate: ExtensionUpdateCheckerDelegate()
4041
)
41-
let statusChecker: AuthStatusChecker = AuthStatusChecker()
4242
var xpcExtensionService: XPCExtensionService?
4343
private var cancellables = Set<AnyCancellable>()
4444
private var progressView: NSProgressIndicator?
45-
private var idleIcon = NSImage(named: "MenuBarIcon")
4645

4746
func applicationDidFinishLaunching(_: Notification) {
4847
if ProcessInfo.processInfo.environment["IS_UNIT_TEST"] == "YES" { return }
4948
_ = XcodeInspector.shared
50-
service.markAsProcessing = { [weak self] in
51-
guard let self = self else { return }
52-
self.markAsProcessing($0)
53-
}
5449
service.start()
5550
AXIsProcessTrustedWithOptions([
5651
kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true,
@@ -63,7 +58,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
6358
buildStatusBarMenu()
6459
watchServiceStatus()
6560
watchAXStatus()
66-
updateStatusBarItem() // set the initial status
61+
watchAuthStatus()
62+
setInitialStatusBarStatus()
6763
}
6864

6965
@objc func quit() {
@@ -183,16 +179,44 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
183179
}
184180
}
185181

182+
func watchAuthStatus() {
183+
let notifications = DistributedNotificationCenter.default().notifications(named: .authStatusDidChange)
184+
Task { [weak self] in
185+
for await _ in notifications {
186+
guard let self else { return }
187+
await self.forceAuthStatusCheck()
188+
}
189+
}
190+
}
191+
192+
func setInitialStatusBarStatus() {
193+
Task {
194+
let authStatus = await Status.shared.getAuthStatus()
195+
if authStatus == .unknown {
196+
// temporarily kick off a language server instance to prime the initial auth status
197+
await forceAuthStatusCheck()
198+
}
199+
updateStatusBarItem()
200+
}
201+
}
202+
203+
func forceAuthStatusCheck() async {
204+
do {
205+
let service = try GitHubCopilotService()
206+
_ = try await service.checkStatus()
207+
try await service.shutdown()
208+
try await service.exit()
209+
} catch {
210+
Logger.service.error("Failed to read auth status: \(error)")
211+
}
212+
}
213+
186214
func updateStatusBarItem() {
187215
Task { @MainActor in
188216
let status = await Status.shared.getStatus()
189-
let image = if status.system {
190-
NSImage(systemSymbolName: status.icon, accessibilityDescription: nil)
191-
} else {
192-
NSImage(named: status.icon)
193-
}
194-
idleIcon = image
217+
let image = status.icon.nsImage
195218
self.statusBarItem.button?.image = image
219+
self.authMenuItem.title = status.authMessage
196220
if let message = status.message {
197221
// TODO switch to attributedTitle to enable line breaks and color.
198222
self.statusMenuItem.title = message
@@ -201,6 +225,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
201225
} else {
202226
self.statusMenuItem.isHidden = true
203227
}
228+
self.markAsProcessing(status.inProgress)
204229
}
205230
}
206231

@@ -209,7 +234,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
209234
// No longer in progress
210235
progressView?.removeFromSuperview()
211236
progressView = nil
212-
statusBarItem.button?.image = idleIcon
213237
return
214238
}
215239
if progressView != nil {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy