Skip to content

Commit

Permalink
Adopts ILanguageFeatureDebounceService#for for inline completions. See
Browse files Browse the repository at this point in the history
  • Loading branch information
hediet committed Feb 8, 2022
1 parent 200beb1 commit 05524c8
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ import { IActiveCodeEditor } from 'vs/editor/browser/editorBrowser';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { InlineCompletionTriggerKind } from 'vs/editor/common/languages';
import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { GhostText, GhostTextWidgetModel } from 'vs/editor/contrib/inlineCompletions/browser/ghostText';
import { InlineCompletionsModel, SynchronizedInlineCompletionsCache, TrackedInlineCompletions } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsModel';
import { SuggestWidgetPreviewModel } from 'vs/editor/contrib/inlineCompletions/browser/suggestWidgetPreviewModel';
import { createDisposableRef } from 'vs/editor/contrib/inlineCompletions/browser/utils';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';

export abstract class DelegatingModel extends Disposable implements GhostTextWidgetModel {
private readonly onDidChangeEmitter = new Emitter<void>();
Expand Down Expand Up @@ -69,8 +67,8 @@ export abstract class DelegatingModel extends Disposable implements GhostTextWid
*/
export class GhostTextModel extends DelegatingModel implements GhostTextWidgetModel {
public readonly sharedCache = this._register(new SharedInlineCompletionCache());
public readonly suggestWidgetAdapterModel = this._register(new SuggestWidgetPreviewModel(this.editor, this.sharedCache, this.languageFeaturesService));
public readonly inlineCompletionsModel = this._register(new InlineCompletionsModel(this.editor, this.sharedCache, this.commandService, this.languageConfigurationService, this.languageFeaturesService));
public readonly suggestWidgetAdapterModel = this._register(this.instantiationService.createInstance(SuggestWidgetPreviewModel, this.editor, this.sharedCache));
public readonly inlineCompletionsModel = this._register(this.instantiationService.createInstance(InlineCompletionsModel, this.editor, this.sharedCache));

public get activeInlineCompletionsModel(): InlineCompletionsModel | undefined {
if (this.targetModel === this.inlineCompletionsModel) {
Expand All @@ -81,9 +79,7 @@ export class GhostTextModel extends DelegatingModel implements GhostTextWidgetMo

constructor(
private readonly editor: IActiveCodeEditor,
@ICommandService private readonly commandService: ICommandService,
@ILanguageConfigurationService private readonly languageConfigurationService: ILanguageConfigurationService,
@ILanguageFeaturesService private readonly languageFeaturesService: ILanguageFeaturesService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
) {
super();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,56 +26,80 @@ import { ILanguageConfigurationService } from 'vs/editor/common/languages/langua
import { fixBracketsInLine } from 'vs/editor/common/model/bracketPairsTextModelPart/fixBrackets';
import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { IFeatureDebounceInformation, ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce';

export class InlineCompletionsModel extends Disposable implements GhostTextWidgetModel {
export class InlineCompletionsModel
extends Disposable
implements GhostTextWidgetModel {
protected readonly onDidChangeEmitter = new Emitter<void>();
public readonly onDidChange = this.onDidChangeEmitter.event;

public readonly completionSession = this._register(new MutableDisposable<InlineCompletionsSession>());
public readonly completionSession = this._register(
new MutableDisposable<InlineCompletionsSession>()
);

private active: boolean = false;
private disposed = false;
private readonly debounceValue = this.debounceService.for(
this.languageFeaturesService.inlineCompletionsProvider,
'InlineCompletionsDebounce',
{ min: 50, max: 200 }
);

constructor(
private readonly editor: IActiveCodeEditor,
private readonly cache: SharedInlineCompletionCache,
@ICommandService private readonly commandService: ICommandService,
@ILanguageConfigurationService private readonly languageConfigurationService: ILanguageConfigurationService,
@ILanguageFeaturesService private readonly languageFeaturesService: ILanguageFeaturesService,
@ILanguageConfigurationService
private readonly languageConfigurationService: ILanguageConfigurationService,
@ILanguageFeaturesService
private readonly languageFeaturesService: ILanguageFeaturesService,
@ILanguageFeatureDebounceService
private readonly debounceService: ILanguageFeatureDebounceService
) {
super();

this._register(commandService.onDidExecuteCommand(e => {
// These commands don't trigger onDidType.
const commands = new Set([
CoreEditingCommands.Tab.id,
CoreEditingCommands.DeleteLeft.id,
CoreEditingCommands.DeleteRight.id,
inlineSuggestCommitId,
'acceptSelectedSuggestion'
]);
if (commands.has(e.commandId) && editor.hasTextFocus()) {
this.handleUserInput();
}
}));
this._register(
commandService.onDidExecuteCommand((e) => {
// These commands don't trigger onDidType.
const commands = new Set([
CoreEditingCommands.Tab.id,
CoreEditingCommands.DeleteLeft.id,
CoreEditingCommands.DeleteRight.id,
inlineSuggestCommitId,
'acceptSelectedSuggestion',
]);
if (commands.has(e.commandId) && editor.hasTextFocus()) {
this.handleUserInput();
}
})
);

this._register(this.editor.onDidType((e) => {
this.handleUserInput();
}));
this._register(
this.editor.onDidType((e) => {
this.handleUserInput();
})
);

this._register(this.editor.onDidChangeCursorPosition((e) => {
if (this.session && !this.session.isValid) {
this.hide();
}
}));
this._register(
this.editor.onDidChangeCursorPosition((e) => {
if (this.session && !this.session.isValid) {
this.hide();
}
})
);

this._register(toDisposable(() => {
this.disposed = true;
}));
this._register(
toDisposable(() => {
this.disposed = true;
})
);

this._register(this.editor.onDidBlurEditorWidget(() => {
this.hide();
}));
this._register(
this.editor.onDidBlurEditorWidget(() => {
this.hide();
})
);
}

private handleUserInput() {
Expand Down Expand Up @@ -146,7 +170,8 @@ export class InlineCompletionsModel extends Disposable implements GhostTextWidge
this.cache,
triggerKind,
this.languageConfigurationService,
this.languageFeaturesService.inlineCompletionsProvider
this.languageFeaturesService.inlineCompletionsProvider,
this.debounceValue
);
this.completionSession.value.takeOwnership(
this.completionSession.value.onDidChange(() => {
Expand Down Expand Up @@ -199,7 +224,8 @@ export class InlineCompletionsSession extends BaseGhostTextWidgetModel {
private readonly cache: SharedInlineCompletionCache,
private initialTriggerKind: InlineCompletionTriggerKind,
private readonly languageConfigurationService: ILanguageConfigurationService,
private readonly registry: LanguageFeatureRegistry<InlineCompletionsProvider>
private readonly registry: LanguageFeatureRegistry<InlineCompletionsProvider>,
private readonly debounce: IFeatureDebounceInformation,
) {
super(editor);

Expand Down Expand Up @@ -231,7 +257,7 @@ export class InlineCompletionsSession extends BaseGhostTextWidgetModel {
}));

this._register(this.registry.onDidChange(() => {
this.updateSoon.schedule();
this.updateSoon.schedule(this.debounce.get(this.editor.getModel()));
}));

this.scheduleAutomaticUpdate();
Expand Down Expand Up @@ -336,7 +362,7 @@ export class InlineCompletionsSession extends BaseGhostTextWidgetModel {
// Since updateSoon debounces, starvation can happen.
// To prevent stale cache, we clear the current update operation.
this.updateOperation.clear();
this.updateSoon.schedule();
this.updateSoon.schedule(this.debounce.get(this.editor.getModel()));
}

private async update(triggerKind: InlineCompletionTriggerKind): Promise<void> {
Expand All @@ -346,6 +372,8 @@ export class InlineCompletionsSession extends BaseGhostTextWidgetModel {

const position = this.editor.getPosition();

const startTime = new Date();

const promise = createCancelablePromise(async token => {
let result;
try {
Expand All @@ -355,6 +383,10 @@ export class InlineCompletionsSession extends BaseGhostTextWidgetModel {
token,
this.languageConfigurationService
);

const endTime = new Date();
this.debounce.update(this.editor.getModel(), endTime.getTime() - startTime.getTime());

} catch (e) {
onUnexpectedError(e);
return;
Expand Down

0 comments on commit 05524c8

Please sign in to comment.