Skip to content

Commit 138856f

Browse files
committed
Support change notification
1 parent 32f429f commit 138856f

File tree

4 files changed

+66
-8
lines changed

4 files changed

+66
-8
lines changed

Core/Sources/CopilotService/CopilotService.swift

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ public protocol CopilotSuggestionServiceType {
2626
) async throws -> [CopilotCompletion]
2727
func notifyAccepted(_ completion: CopilotCompletion) async
2828
func notifyRejected(_ completions: [CopilotCompletion]) async
29-
func openTextDocument(fileURL: URL, content: String) async throws
29+
func notifyOpenTextDocument(fileURL: URL, content: String) async throws
30+
func notifyChangeTextDocument(fileURL: URL, content: String) async throws
31+
func notifyCloseTextDocument(fileURL: URL) async throws
32+
func notifySaveTextDocument(fileURL: URL) async throws
3033
}
3134

3235
protocol CopilotLSP {
@@ -252,13 +255,13 @@ public final class CopilotSuggestionService: CopilotBaseService, CopilotSuggesti
252255
)
253256
}
254257

255-
public func openTextDocument(
258+
public func notifyOpenTextDocument(
256259
fileURL: URL,
257260
content: String
258261
) async throws {
259262
let languageId = languageIdentifierFromFileURL(fileURL)
260263
let uri = "file://\(fileURL.path)"
261-
Logger.service.debug(uri)
264+
Logger.service.debug("Open \(uri)")
262265
try await server.sendNotification(
263266
.didOpenTextDocument(
264267
DidOpenTextDocumentParams(
@@ -272,6 +275,36 @@ public final class CopilotSuggestionService: CopilotBaseService, CopilotSuggesti
272275
)
273276
)
274277
}
278+
279+
public func notifyChangeTextDocument(fileURL: URL, content: String) async throws {
280+
let languageId = languageIdentifierFromFileURL(fileURL)
281+
let uri = "file://\(fileURL.path)"
282+
Logger.service.debug("Change \(uri)")
283+
try await server.sendNotification(
284+
.didOpenTextDocument(
285+
DidOpenTextDocumentParams(
286+
textDocument: .init(
287+
uri: uri,
288+
languageId: languageId.rawValue,
289+
version: 0,
290+
text: content
291+
)
292+
)
293+
)
294+
)
295+
}
296+
297+
public func notifySaveTextDocument(fileURL: URL) async throws {
298+
let uri = "file://\(fileURL.path)"
299+
Logger.service.debug("Save \(uri)")
300+
try await server.sendNotification(.didSaveTextDocument(.init(uri: uri)))
301+
}
302+
303+
public func notifyCloseTextDocument(fileURL: URL) async throws {
304+
let uri = "file://\(fileURL.path)"
305+
Logger.service.debug("Close \(uri)")
306+
try await server.sendNotification(.didCloseTextDocument(.init(uri: uri)))
307+
}
275308
}
276309

277310
extension InitializingServer: CopilotLSP {

Core/Sources/Service/RealtimeSuggestionController.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ public class RealtimeSuggestionController {
131131
switch notification.name {
132132
case kAXValueChangedNotification:
133133
self.triggerPrefetchDebounced()
134+
await self.notifyEditingFileChange(editor: focusElement)
134135
default:
135136
continue
136137
}
@@ -207,7 +208,7 @@ public class RealtimeSuggestionController {
207208

208209
guard UserDefaults.shared.value(for: \.realtimeSuggestionToggle)
209210
else { return }
210-
211+
211212
if UserDefaults.shared.value(for: \.disableSuggestionFeatureGlobally),
212213
let fileURL = try? await Environment.fetchCurrentFileURL(),
213214
let (workspace, _) = try? await Workspace
@@ -216,7 +217,7 @@ public class RealtimeSuggestionController {
216217
let isEnabled = workspace.isSuggestionFeatureEnabled
217218
if !isEnabled { return }
218219
}
219-
220+
220221
if Task.isCancelled { return }
221222

222223
Logger.service.info("Prefetch suggestions.")
@@ -264,4 +265,12 @@ public class RealtimeSuggestionController {
264265
let application = AXUIElementCreateApplication(activeXcode.processIdentifier)
265266
return application.focusedWindow?.child(identifier: "_XC_COMPLETION_TABLE_") != nil
266267
}
268+
269+
func notifyEditingFileChange(editor: AXUIElement) async {
270+
guard let fileURL = try? await Environment.fetchCurrentFileURL(),
271+
let (workspace, filespace) = try? await Workspace
272+
.fetchOrCreateWorkspaceIfNeeded(fileURL: fileURL)
273+
else { return }
274+
workspace.notifyUpdateFile(filespace: filespace, content: editor.value)
275+
}
267276
}

Core/Sources/Service/SuggestionCommandHandler/WindowBaseCommandHandler.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ struct WindowBaseCommandHandler: SuggestionCommandHandler {
147147
defer { presenter.markAsProcessing(false) }
148148

149149
let fileURL = try await Environment.fetchCurrentFileURL()
150-
let (workspace, _) = try await Workspace.fetchOrCreateWorkspaceIfNeeded(fileURL: fileURL)
150+
let (workspace, filespace) = try await Workspace.fetchOrCreateWorkspaceIfNeeded(fileURL: fileURL)
151151

152152
let injector = SuggestionInjector()
153153
var lines = editor.lines
@@ -199,11 +199,15 @@ struct WindowBaseCommandHandler: SuggestionCommandHandler {
199199

200200
presenter.discardSuggestion(fileURL: fileURL)
201201

202-
return .init(
202+
let result = UpdatedContent(
203203
content: String(lines.joined(separator: "")),
204204
newSelection: .cursor(cursorPosition),
205205
modifications: extraInfo.modifications
206206
)
207+
208+
workspace.notifyUpdateFile(filespace: filespace, content: result.content)
209+
210+
return result
207211
}
208212

209213
return nil

Core/Sources/Service/Workspace.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,18 +303,30 @@ extension Workspace {
303303

304304
func notifyOpenFile(filespace: Filespace) {
305305
Task {
306-
try await copilotSuggestionService?.openTextDocument(
306+
try await copilotSuggestionService?.notifyOpenTextDocument(
307307
fileURL: filespace.fileURL,
308308
content: try String(contentsOf: filespace.fileURL, encoding: .utf8)
309309
)
310310
}
311311
}
312+
313+
func notifyUpdateFile(filespace: Filespace, content: String) {
314+
Task {
315+
try await copilotSuggestionService?.notifyChangeTextDocument(
316+
fileURL: filespace.fileURL,
317+
content: content
318+
)
319+
}
320+
}
312321
}
313322

314323
extension Workspace {
315324
func cleanUp() {
316325
for (fileURL, filespace) in filespaces {
317326
if filespace.isExpired {
327+
Task {
328+
try await copilotSuggestionService?.notifyCloseTextDocument(fileURL: fileURL)
329+
}
318330
filespaces[fileURL] = nil
319331
}
320332
}

0 commit comments

Comments
 (0)