@@ -8,6 +8,9 @@ import { equalsIfDefined, itemEquals } from '../../../../../base/common/equals.j
8
8
import { matchesSubString } from '../../../../../base/common/filters.js' ;
9
9
import { Disposable , IDisposable , MutableDisposable } from '../../../../../base/common/lifecycle.js' ;
10
10
import { IObservable , IReader , ITransaction , derivedOpts , disposableObservableValue , transaction } from '../../../../../base/common/observable.js' ;
11
+ import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js' ;
12
+ import { ILogService } from '../../../../../platform/log/common/log.js' ;
13
+ import { observableConfigValue } from '../../../../../platform/observable/common/platformObservableUtils.js' ;
11
14
import { Position } from '../../../../common/core/position.js' ;
12
15
import { Range } from '../../../../common/core/range.js' ;
13
16
import { SingleTextEdit } from '../../../../common/core/textEdit.js' ;
@@ -21,16 +24,22 @@ import { InlineCompletionItem, InlineCompletionProviderResult, provideInlineComp
21
24
import { singleTextRemoveCommonPrefix } from './singleTextEditHelpers.js' ;
22
25
23
26
export class InlineCompletionsSource extends Disposable {
27
+ private static _requestId = 0 ;
28
+
24
29
private readonly _updateOperation = this . _register ( new MutableDisposable < UpdateOperation > ( ) ) ;
25
30
public readonly inlineCompletions = disposableObservableValue < UpToDateInlineCompletions | undefined > ( 'inlineCompletions' , undefined ) ;
26
31
public readonly suggestWidgetInlineCompletions = disposableObservableValue < UpToDateInlineCompletions | undefined > ( 'suggestWidgetInlineCompletions' , undefined ) ;
27
32
33
+ private readonly _loggingEnabled = observableConfigValue ( 'editor.inlineSuggest.logFetch' , false , this . _configurationService ) . recomputeInitiallyAndOnChange ( this . _store ) ;
34
+
28
35
constructor (
29
36
private readonly _textModel : ITextModel ,
30
37
private readonly _versionId : IObservable < number | null > ,
31
38
private readonly _debounceValue : IFeatureDebounceInformation ,
32
39
@ILanguageFeaturesService private readonly _languageFeaturesService : ILanguageFeaturesService ,
33
40
@ILanguageConfigurationService private readonly _languageConfigurationService : ILanguageConfigurationService ,
41
+ @ILogService private readonly _logService : ILogService ,
42
+ @IConfigurationService private readonly _configurationService : IConfigurationService ,
34
43
) {
35
44
super ( ) ;
36
45
@@ -39,6 +48,10 @@ export class InlineCompletionsSource extends Disposable {
39
48
} ) ) ;
40
49
}
41
50
51
+ private _log ( entry : { kind : 'start' ; uri : string ; modelVersion : number ; requestId : number ; context : unknown } | { kind : 'end' ; error : any ; durationMs : number ; result : unknown ; requestId : number } ) {
52
+ this . _logService . info ( 'InlineCompletionsSource.fetch ' + JSON . stringify ( entry ) ) ;
53
+ }
54
+
42
55
public fetch ( position : Position , context : InlineCompletionContext , activeInlineCompletion : InlineCompletionWithUpdatedRange | undefined ) : Promise < boolean > {
43
56
const request = new UpdateRequest ( position , context , this . _textModel . getVersionId ( ) ) ;
44
57
@@ -66,15 +79,40 @@ export class InlineCompletionsSource extends Disposable {
66
79
return false ;
67
80
}
68
81
82
+ const requestId = InlineCompletionsSource . _requestId ++ ;
83
+ if ( this . _loggingEnabled . get ( ) ) {
84
+ this . _log ( { kind : 'start' , requestId, uri : this . _textModel . uri . toString ( ) , modelVersion : this . _textModel . getVersionId ( ) , context : { triggerKind : context . triggerKind } } ) ;
85
+ }
86
+
69
87
const startTime = new Date ( ) ;
70
- const updatedCompletions = await provideInlineCompletions (
71
- this . _languageFeaturesService . inlineCompletionsProvider ,
72
- position ,
73
- this . _textModel ,
74
- context ,
75
- source . token ,
76
- this . _languageConfigurationService
77
- ) ;
88
+ let updatedCompletions : InlineCompletionProviderResult | undefined = undefined ;
89
+ let error : any = undefined ;
90
+ try {
91
+ updatedCompletions = await provideInlineCompletions (
92
+ this . _languageFeaturesService . inlineCompletionsProvider ,
93
+ position ,
94
+ this . _textModel ,
95
+ context ,
96
+ source . token ,
97
+ this . _languageConfigurationService
98
+ ) ;
99
+ } catch ( e ) {
100
+ error = e ;
101
+ throw e ;
102
+ } finally {
103
+ if ( this . _loggingEnabled . get ( ) ) {
104
+ if ( source . token . isCancellationRequested ) {
105
+ error = 'canceled' ;
106
+ }
107
+ const result = updatedCompletions ?. completions . map ( c => ( {
108
+ range : c . range . toString ( ) ,
109
+ text : c . insertText ,
110
+ isInlineEdit : ! ! c . sourceInlineCompletion . isInlineEdit ,
111
+ source : c . source . provider . groupId ,
112
+ } ) ) ;
113
+ this . _log ( { kind : 'end' , requestId, durationMs : ( Date . now ( ) - startTime . getTime ( ) ) , error, result } ) ;
114
+ }
115
+ }
78
116
79
117
if ( source . token . isCancellationRequested || this . _store . isDisposed || this . _textModel . getVersionId ( ) !== request . versionId ) {
80
118
return false ;
@@ -273,6 +311,7 @@ export class InlineCompletionWithUpdatedRange {
273
311
! updatedRange
274
312
|| ! this . inlineCompletion . range . getStartPosition ( ) . equals ( updatedRange . getStartPosition ( ) )
275
313
|| cursorPosition . lineNumber !== minimizedReplacement . range . startLineNumber
314
+ || minimizedReplacement . isEmpty // if the completion is empty after removing the common prefix of the completion and the model, the completion item would not be visible
276
315
) {
277
316
return false ;
278
317
}
0 commit comments