@@ -44,8 +44,10 @@ function fromId(id: string | undefined): AnnotationState | undefined {
44
44
interface AnnotationState {
45
45
id : string
46
46
suppressWhileRunning : boolean
47
+
47
48
text : ( ) => string
48
- nextState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState | undefined
49
+ updateState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState | undefined
50
+ isNextState ( state : AnnotationState | undefined ) : boolean
49
51
}
50
52
51
53
/**
@@ -67,7 +69,7 @@ class AutotriggerState implements AnnotationState {
67
69
text = ( ) => 'CodeWhisperer Tip 1/3: Start typing to get suggestions ([ESC] to exit)'
68
70
static acceptedCount = 0
69
71
70
- nextState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState | undefined {
72
+ updateState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState | undefined {
71
73
if ( AutotriggerState . acceptedCount < RecommendationService . instance . acceptedSuggestionCount ) {
72
74
return new ManualtriggerState ( )
73
75
} else if ( session . recommendations . length > 0 && RecommendationHandler . instance . isSuggestionVisible ( ) ) {
@@ -76,6 +78,10 @@ class AutotriggerState implements AnnotationState {
76
78
return this
77
79
}
78
80
}
81
+
82
+ isNextState ( state : AnnotationState | undefined ) : boolean {
83
+ return state instanceof ManualtriggerState
84
+ }
79
85
}
80
86
81
87
/**
@@ -92,10 +98,15 @@ class PressTabState implements AnnotationState {
92
98
id = PressTabState . id
93
99
94
100
suppressWhileRunning = false
101
+
95
102
text = ( ) => 'CodeWhisperer Tip 1/3: Press [TAB] to accept ([ESC] to exit)'
96
103
97
- nextState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState | undefined {
98
- return new AutotriggerState ( ) . nextState ( changeSource , force )
104
+ updateState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState | undefined {
105
+ return new AutotriggerState ( ) . updateState ( changeSource , force )
106
+ }
107
+
108
+ isNextState ( state : AnnotationState | undefined ) : boolean {
109
+ return state instanceof ManualtriggerState
99
110
}
100
111
}
101
112
@@ -124,7 +135,7 @@ class ManualtriggerState implements AnnotationState {
124
135
hasManualTrigger : boolean = false
125
136
hasValidResponse : boolean = false
126
137
127
- nextState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState | undefined {
138
+ updateState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState | undefined {
128
139
if ( this . hasManualTrigger && this . hasValidResponse ) {
129
140
if ( changeSource !== 'codewhisperer' ) {
130
141
return new TryMoreExState ( )
@@ -135,6 +146,10 @@ class ManualtriggerState implements AnnotationState {
135
146
return this
136
147
}
137
148
}
149
+
150
+ isNextState ( state : AnnotationState | undefined ) : boolean {
151
+ return state instanceof TryMoreExState
152
+ }
138
153
}
139
154
140
155
/**
@@ -153,13 +168,17 @@ class TryMoreExState implements AnnotationState {
153
168
suppressWhileRunning = true
154
169
155
170
text = ( ) => 'CodeWhisperer Tip 3/3: For settings, open the CodeWhisperer menu from the status bar ([ESC] to exit)'
156
- nextState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState {
171
+ updateState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState {
157
172
if ( force ) {
158
173
return new EndState ( )
159
174
}
160
175
return this
161
176
}
162
177
178
+ isNextState ( state : AnnotationState | undefined ) : boolean {
179
+ return state instanceof EndState
180
+ }
181
+
163
182
static triggerCount : number = 0
164
183
static learnmoeCount : number = 0
165
184
}
@@ -170,9 +189,12 @@ class EndState implements AnnotationState {
170
189
171
190
suppressWhileRunning = true
172
191
text = ( ) => ''
173
- nextState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState {
192
+ updateState ( changeSource : AnnotationChangeSource , force : boolean ) : AnnotationState {
174
193
return this
175
194
}
195
+ isNextState ( state : AnnotationState ) : boolean {
196
+ return false
197
+ }
176
198
}
177
199
178
200
/**
@@ -192,8 +214,6 @@ export class LineAnnotationController implements vscode.Disposable {
192
214
193
215
private _currentState : AnnotationState
194
216
195
- private _seen : Set < string > = new Set ( )
196
-
197
217
private readonly cwLineHintDecoration : vscode . TextEditorDecorationType =
198
218
vscode . window . createTextEditorDecorationType ( {
199
219
after : {
@@ -262,7 +282,7 @@ export class LineAnnotationController implements vscode.Disposable {
262
282
try {
263
283
telemetry . ui_click . emit ( { elementId : `dismiss_${ this . _currentState . id } ` } )
264
284
} catch ( _ ) { }
265
- await this . markTutorialDone ( )
285
+ await this . dismissTutorial ( )
266
286
getLogger ( ) . debug ( `codewhisperer: user dismiss tutorial.` )
267
287
}
268
288
} )
@@ -284,7 +304,7 @@ export class LineAnnotationController implements vscode.Disposable {
284
304
return this . _currentState . id === new EndState ( ) . id
285
305
}
286
306
287
- async markTutorialDone ( ) {
307
+ async dismissTutorial ( ) {
288
308
this . _currentState = new EndState ( )
289
309
await vscode . commands . executeCommand ( 'setContext' , inlinehintWipKey , false )
290
310
await set ( inlinehintKey , this . _currentState . id , globals . context . globalState )
@@ -384,14 +404,13 @@ export class LineAnnotationController implements vscode.Disposable {
384
404
// special case
385
405
// Endstate is meaningless and doesnt need to be rendered
386
406
this . clear ( )
387
- await this . markTutorialDone ( )
407
+ await this . dismissTutorial ( )
388
408
return
389
409
} else if ( decorationOptions . renderOptions ?. after ?. contentText === new TryMoreExState ( ) . text ( ) ) {
390
410
// special case
391
411
// case 3 exit criteria is to fade away in 30s
392
412
setTimeout ( async ( ) => {
393
- await this . markTutorialDone ( )
394
- await this . refresh ( editor , source )
413
+ await this . refresh ( editor , source , true )
395
414
} , case3TimeWindow )
396
415
}
397
416
@@ -423,21 +442,23 @@ export class LineAnnotationController implements vscode.Disposable {
423
442
return undefined
424
443
}
425
444
426
- const nextState : AnnotationState | undefined = this . _currentState . nextState ( source , force ?? false )
445
+ const updatedState : AnnotationState | undefined = this . _currentState . updateState ( source , force ?? false )
427
446
428
- if ( nextState === undefined ) {
447
+ if ( updatedState === undefined ) {
429
448
return undefined
430
449
}
431
450
432
- if ( ! this . _seen . has ( nextState . id ) ) {
433
- try {
434
- telemetry . ui_click . emit ( { elementId : this . _currentState . id , passive : true } )
435
- } catch ( e ) { }
451
+ if ( this . _currentState . isNextState ( updatedState ) ) {
452
+ // special case because PressTabState is part of case_1 (1a) which possibly jumps directly from case_1a to case_2 and miss case_1
453
+ if ( this . _currentState instanceof PressTabState ) {
454
+ telemetry . ui_click . emit ( { elementId : AutotriggerState . id , passive : true } )
455
+ }
456
+ telemetry . ui_click . emit ( { elementId : this . _currentState . id , passive : true } )
436
457
}
437
458
438
459
// update state
439
- this . _currentState = nextState
440
- this . _seen . add ( this . _currentState . id )
460
+ this . _currentState = updatedState
461
+
441
462
// take snapshot of accepted session so that we can compre if there is delta -> users accept 1 suggestion after seeing this state
442
463
AutotriggerState . acceptedCount = RecommendationService . instance . acceptedSuggestionCount
443
464
// take snapshot of total trigger count so that we can compare if there is delta -> users accept/reject suggestions after seeing this state
0 commit comments