Skip to content

Commit a6f2d9e

Browse files
committed
document change
1 parent 3b2654f commit a6f2d9e

File tree

3 files changed

+76
-31
lines changed

3 files changed

+76
-31
lines changed

packages/amazonq/src/app/inline/completion.ts

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
import * as vscode from 'vscode'
5+
66
import {
77
CancellationToken,
88
InlineCompletionContext,
@@ -46,11 +46,7 @@ import { Experiments, getLogger, sleep } from 'aws-core-vscode/shared'
4646
import { debounce, messageUtils } from 'aws-core-vscode/utils'
4747
import { showEdits } from './EditRendering/imageRenderer'
4848
import { ICursorUpdateRecorder } from './cursorUpdateManager'
49-
50-
let lastDocumentDeleteEvent: vscode.TextDocumentChangeEvent | undefined = undefined
51-
let lastDocumentDeleteTime = 0
52-
53-
let lastDocumentChangeEventMap: Map<string, vscode.TextDocumentChangeEvent> = new Map()
49+
import { DocumentEventListener } from './documentEventListener'
5450

5551
export class InlineCompletionManager implements Disposable {
5652
private disposable: Disposable
@@ -62,7 +58,7 @@ export class InlineCompletionManager implements Disposable {
6258

6359
private inlineTutorialAnnotation: InlineTutorialAnnotation
6460
private readonly logSessionResultMessageName = 'aws/logInlineCompletionSessionResults'
65-
private documentChangeListener: Disposable
61+
private documentEventListener: DocumentEventListener
6662

6763
constructor(
6864
languageClient: LanguageClient,
@@ -76,27 +72,19 @@ export class InlineCompletionManager implements Disposable {
7672
this.lineTracker = lineTracker
7773
this.recommendationService = new RecommendationService(this.sessionManager, cursorUpdateRecorder)
7874
this.inlineTutorialAnnotation = inlineTutorialAnnotation
75+
this.documentEventListener = new DocumentEventListener()
7976
this.inlineCompletionProvider = new AmazonQInlineCompletionItemProvider(
8077
languageClient,
8178
this.recommendationService,
8279
this.sessionManager,
83-
this.inlineTutorialAnnotation
80+
this.inlineTutorialAnnotation,
81+
this.documentEventListener
8482
)
8583

86-
this.documentChangeListener = vscode.workspace.onDidChangeTextDocument((e) => {
87-
if (e.contentChanges.length === 1 && e.contentChanges[0].text === '') {
88-
lastDocumentDeleteEvent = e
89-
lastDocumentDeleteTime = performance.now()
90-
}
91-
if (e.contentChanges.length > 0) {
92-
lastDocumentChangeEventMap.set(e.document.uri.fsPath, e)
93-
}
94-
})
9584
this.disposable = languages.registerInlineCompletionItemProvider(
9685
CodeWhispererConstants.platformLanguageIds,
9786
this.inlineCompletionProvider
9887
)
99-
10088
this.lineTracker.ready()
10189
}
10290

@@ -109,8 +97,8 @@ export class InlineCompletionManager implements Disposable {
10997
this.disposable.dispose()
11098
this.lineTracker.dispose()
11199
}
112-
if (this.documentChangeListener) {
113-
this.documentChangeListener.dispose()
100+
if (this.documentEventListener) {
101+
this.documentEventListener.dispose()
114102
}
115103
}
116104

@@ -216,7 +204,8 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
216204
private readonly languageClient: LanguageClient,
217205
private readonly recommendationService: RecommendationService,
218206
private readonly sessionManager: SessionManager,
219-
private readonly inlineTutorialAnnotation: InlineTutorialAnnotation
207+
private readonly inlineTutorialAnnotation: InlineTutorialAnnotation,
208+
private readonly documentEventListener: DocumentEventListener
220209
) {}
221210

222211
private readonly logSessionResultMessageName = 'aws/logInlineCompletionSessionResults'
@@ -256,14 +245,11 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
256245
await sleep(1)
257246
// prevent user deletion invoking auto trigger
258247
// this is a best effort estimate of deletion
259-
const timeDiff = Math.abs(performance.now() - lastDocumentDeleteTime)
260-
if (timeDiff < 500 && lastDocumentDeleteEvent && lastDocumentDeleteEvent.document.uri === document.uri) {
248+
if (this.documentEventListener.isLastEventDeletion(document.uri.fsPath)) {
261249
getLogger().debug('Skip auto trigger when deleting code')
262250
return []
263251
}
264252

265-
const event = lastDocumentChangeEventMap.get(document.uri.fsPath) || undefined
266-
console.log(event)
267253
let logstr = `GenerateCompletion metadata:\\n`
268254
try {
269255
const t0 = performance.now()
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import * as vscode from 'vscode'
6+
7+
export interface DocumentChangeEvent {
8+
event: vscode.TextDocumentChangeEvent
9+
timestamp: number
10+
}
11+
12+
export class DocumentEventListener {
13+
private lastDocumentChangeEventMap: Map<string, DocumentChangeEvent> = new Map()
14+
private documentChangeListener: vscode.Disposable
15+
private _maxDocument = 1000
16+
17+
constructor() {
18+
this.documentChangeListener = vscode.workspace.onDidChangeTextDocument((e) => {
19+
if (e.contentChanges.length > 0) {
20+
if (this.lastDocumentChangeEventMap.size > this._maxDocument) {
21+
this.lastDocumentChangeEventMap.clear()
22+
}
23+
this.lastDocumentChangeEventMap.set(e.document.uri.fsPath, { event: e, timestamp: performance.now() })
24+
}
25+
})
26+
}
27+
28+
public isLastEventDeletion(filepath: string): boolean {
29+
const result = this.lastDocumentChangeEventMap.get(filepath)
30+
if (result) {
31+
const event = result.event
32+
const eventTime = result.timestamp
33+
const isDelete =
34+
(event && event.contentChanges.length === 1 && event.contentChanges[0].text === '') || false
35+
const timeDiff = Math.abs(performance.now() - eventTime)
36+
return timeDiff < 500 && isDelete
37+
}
38+
return false
39+
}
40+
41+
public getLastDocumentChangeEvent(filepath: string): DocumentChangeEvent | undefined {
42+
return this.lastDocumentChangeEventMap.get(filepath)
43+
}
44+
45+
public dispose(): void {
46+
if (this.documentChangeListener) {
47+
this.documentChangeListener.dispose()
48+
}
49+
}
50+
}

packages/amazonq/test/unit/amazonq/apps/inline/completion.test.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
} from 'aws-core-vscode/codewhisperer'
2929
import { LineTracker } from '../../../../../src/app/inline/stateTracker/lineTracker'
3030
import { InlineTutorialAnnotation } from '../../../../../src/app/inline/tutorials/inlineTutorialAnnotation'
31+
import { DocumentEventListener } from '../../../../../src/app/inline/documentEventListener'
3132

3233
describe('InlineCompletionManager', () => {
3334
let manager: InlineCompletionManager
@@ -243,11 +244,13 @@ describe('InlineCompletionManager', () => {
243244
let getAllRecommendationsStub: sinon.SinonStub
244245
let recommendationService: RecommendationService
245246
let inlineTutorialAnnotation: InlineTutorialAnnotation
247+
let documentEventListener: DocumentEventListener
246248

247249
beforeEach(() => {
248250
const lineTracker = new LineTracker()
249251
inlineTutorialAnnotation = new InlineTutorialAnnotation(lineTracker, mockSessionManager)
250252
recommendationService = new RecommendationService(mockSessionManager)
253+
documentEventListener = new DocumentEventListener()
251254
vsCodeState.isRecommendationsActive = false
252255
mockSessionManager = {
253256
getActiveSession: getActiveSessionStub,
@@ -271,7 +274,8 @@ describe('InlineCompletionManager', () => {
271274
languageClient,
272275
recommendationService,
273276
mockSessionManager,
274-
inlineTutorialAnnotation
277+
inlineTutorialAnnotation,
278+
documentEventListener
275279
)
276280
const items = await provider.provideInlineCompletionItems(
277281
mockDocument,
@@ -287,7 +291,8 @@ describe('InlineCompletionManager', () => {
287291
languageClient,
288292
recommendationService,
289293
mockSessionManager,
290-
inlineTutorialAnnotation
294+
inlineTutorialAnnotation,
295+
documentEventListener
291296
)
292297
await provider.provideInlineCompletionItems(mockDocument, mockPosition, mockContext, mockToken)
293298
}),
@@ -296,7 +301,8 @@ describe('InlineCompletionManager', () => {
296301
languageClient,
297302
recommendationService,
298303
mockSessionManager,
299-
inlineTutorialAnnotation
304+
inlineTutorialAnnotation,
305+
documentEventListener
300306
)
301307
getActiveRecommendationStub.returns([
302308
{
@@ -326,7 +332,8 @@ describe('InlineCompletionManager', () => {
326332
languageClient,
327333
recommendationService,
328334
mockSessionManager,
329-
inlineTutorialAnnotation
335+
inlineTutorialAnnotation,
336+
documentEventListener
330337
)
331338
const expectedText = `${mockSuggestions[1].insertText}this is my text`
332339
getActiveRecommendationStub.returns([
@@ -352,7 +359,8 @@ describe('InlineCompletionManager', () => {
352359
languageClient,
353360
recommendationService,
354361
mockSessionManager,
355-
inlineTutorialAnnotation
362+
inlineTutorialAnnotation,
363+
documentEventListener
356364
)
357365
getActiveRecommendationStub.returns([])
358366
const messageShown = new Promise((resolve) =>
@@ -385,7 +393,8 @@ describe('InlineCompletionManager', () => {
385393
languageClient,
386394
recommendationService,
387395
mockSessionManager,
388-
inlineTutorialAnnotation
396+
inlineTutorialAnnotation,
397+
documentEventListener
389398
)
390399
const p1 = provider.provideInlineCompletionItems(mockDocument, mockPosition, mockContext, mockToken)
391400
const p2 = provider.provideInlineCompletionItems(mockDocument, mockPosition, mockContext, mockToken)

0 commit comments

Comments
 (0)