Skip to content

Commit 04e3df0

Browse files
authored
fix(codewhisperer): fix auto-trigger regressions (#2947)
## Problem 1. The 15 character keystroke auto-trigger was accidentally removed in fix(codewhisperer) update autotrigger filtering logic and fix enter key autotrigger blocked #2899. 2. Enter auto trigger by \r\n was removed in fix(codewhisperer) update autotrigger filtering logic and fix enter key autotrigger blocked #2899. 3. Reverted the 2 second auto trigger limitation for Special characters | Enter |intelliSense auto triggers which was removed in fix(codewhisperer) update autotrigger filtering logic and fix enter key autotrigger blocked #2899. ## Solution Trigger auto trigger when there are more than 15 keystroke inputs.
1 parent 3a407a0 commit 04e3df0

File tree

3 files changed

+59
-7
lines changed

3 files changed

+59
-7
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "CodeWhisperer auto trigger not working correctly in certain circumstances"
4+
}

src/codewhisperer/service/keyStrokeHandler.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,6 @@ export class KeyStrokeHandler {
5757
// Pause automated trigger when typed input matches recommendation prefix for inline suggestion
5858
if (InlineCompletion.instance.isTypeaheadInProgress) return
5959

60-
// Time duration between 2 invocations should be greater than the threshold
61-
// This threshold does not applies to Enter | SpecialCharacters type auto trigger.
62-
const duration = Math.floor((performance.now() - RecommendationHandler.instance.lastInvocationTime) / 1000)
63-
if (duration < CodeWhispererConstants.invocationTimeIntervalThreshold) return
64-
6560
// Skip Cloud9 IntelliSense acceptance event
6661
if (
6762
isCloud9() &&
@@ -75,6 +70,9 @@ export class KeyStrokeHandler {
7570

7671
let triggerType: CodewhispererAutomatedTriggerType | undefined
7772
const changedSource = new DefaultDocumentChangedType(event.contentChanges).checkChangeSource()
73+
// Time duration between 2 invocations should be greater than the threshold
74+
// This threshold does not applies to Enter | SpecialCharacters | IntelliSenseAcceptance type auto trigger.
75+
const duration = Math.floor((performance.now() - RecommendationHandler.instance.lastInvocationTime) / 1000)
7876
switch (changedSource) {
7977
case DocumentChangedSource.EnterKey: {
8078
this.keyStrokeCount += 1
@@ -89,16 +87,25 @@ export class KeyStrokeHandler {
8987
case DocumentChangedSource.IntelliSense: {
9088
this.keyStrokeCount += 1
9189
triggerType = 'IntelliSenseAcceptance'
90+
9291
break
9392
}
9493
case DocumentChangedSource.RegularKey: {
9594
this.keyStrokeCount += 1
95+
if (
96+
this.keyStrokeCount >= 15 &&
97+
duration >= CodeWhispererConstants.invocationTimeIntervalThreshold
98+
) {
99+
triggerType = 'KeyStrokeCount'
100+
this.keyStrokeCount = 0
101+
}
96102
break
97103
}
98104
default: {
99105
break
100106
}
101107
}
108+
102109
if (triggerType) {
103110
this.invokeAutomatedTrigger(triggerType, editor, client, config)
104111
}
@@ -170,10 +177,13 @@ export abstract class DocumentChangedType {
170177

171178
abstract checkChangeSource(): DocumentChangedSource
172179

173-
// Enter key should always start with ONE '\n' and potentially following spaces due to IDE reformat
180+
// Enter key should always start with ONE '\n' or '\r\n' and potentially following spaces due to IDE reformat
174181
protected isEnterKey(str: string): boolean {
175182
if (str.length === 0) return false
176-
return str[0] === '\n' && str.substring(1).trim().length === 0
183+
return (
184+
(str.startsWith('\r\n') && str.substring(2).trim() === '') ||
185+
(str[0] === '\n' && str.substring(1).trim() === '')
186+
)
177187
}
178188

179189
// Tab should consist of space char only ' ' and the length % tabSize should be 0

src/test/codewhisperer/service/keyStrokeHandler.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,32 @@ describe('keyStrokeHandler', function () {
113113
assert.ok(!invokeSpy.called)
114114
})
115115

116+
it('Should call invokeAutomatedTrigger if previous text input is within 2 seconds but the new input is new line', async function () {
117+
KeyStrokeHandler.instance.keyStrokeCount = 14
118+
const mockEditor = createMockTextEditor()
119+
const mockEvent: vscode.TextDocumentChangeEvent = createTextDocumentChangeEvent(
120+
mockEditor.document,
121+
new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 1)),
122+
'\n'
123+
)
124+
RecommendationHandler.instance.lastInvocationTime = performance.now() - 1500
125+
await KeyStrokeHandler.instance.processKeyStroke(mockEvent, mockEditor, mockClient, config)
126+
assert.ok(invokeSpy.called)
127+
})
128+
129+
it('Should call invokeAutomatedTrigger if previous text input is within 2 seconds but the new input is a specialcharacter', async function () {
130+
KeyStrokeHandler.instance.keyStrokeCount = 14
131+
const mockEditor = createMockTextEditor()
132+
const mockEvent: vscode.TextDocumentChangeEvent = createTextDocumentChangeEvent(
133+
mockEditor.document,
134+
new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 1)),
135+
'('
136+
)
137+
RecommendationHandler.instance.lastInvocationTime = performance.now() - 1500
138+
await KeyStrokeHandler.instance.processKeyStroke(mockEvent, mockEditor, mockClient, config)
139+
assert.ok(invokeSpy.called)
140+
})
141+
116142
it('Should call invokeAutomatedTrigger with Enter when inputing \n', async function () {
117143
const mockEditor = createMockTextEditor()
118144
const mockEvent: vscode.TextDocumentChangeEvent = createTextDocumentChangeEvent(
@@ -125,6 +151,18 @@ describe('keyStrokeHandler', function () {
125151
assert.ok(invokeSpy.called)
126152
})
127153

154+
it('Should call invokeAutomatedTrigger with Enter when inputing \r\n', async function () {
155+
const mockEditor = createMockTextEditor()
156+
const mockEvent: vscode.TextDocumentChangeEvent = createTextDocumentChangeEvent(
157+
mockEditor.document,
158+
new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 2)),
159+
'\r\n'
160+
)
161+
await KeyStrokeHandler.instance.processKeyStroke(mockEvent, mockEditor, mockClient, config)
162+
invokeSpy('Enter', mockEditor, mockClient)
163+
assert.ok(invokeSpy.called)
164+
})
165+
128166
it('Should call invokeAutomatedTrigger with SpecialCharacter when inputing {', async function () {
129167
const mockEditor = createMockTextEditor()
130168
const mockEvent: vscode.TextDocumentChangeEvent = createTextDocumentChangeEvent(

0 commit comments

Comments
 (0)