mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
Improves inline completion provider change event (#252312)
This commit is contained in:
committed by
GitHub
parent
848883ca9c
commit
cacbd7f8ac
@@ -8,7 +8,7 @@ import { itemsEquals } from '../../../../../base/common/equals.js';
|
||||
import { BugIndicatingError, onUnexpectedError, onUnexpectedExternalError } from '../../../../../base/common/errors.js';
|
||||
import { Emitter } from '../../../../../base/common/event.js';
|
||||
import { Disposable } from '../../../../../base/common/lifecycle.js';
|
||||
import { IObservable, IObservableWithChange, IReader, ITransaction, autorun, autorunWithStore, constObservable, derived, derivedHandleChanges, derivedOpts, observableFromEvent, observableSignal, observableValue, recomputeInitiallyAndOnChange, subtransaction, transaction } from '../../../../../base/common/observable.js';
|
||||
import { IObservable, IObservableWithChange, IReader, ITransaction, autorun, constObservable, derived, derivedHandleChanges, derivedOpts, mapObservableArrayCached, observableFromEvent, observableSignal, observableValue, recomputeInitiallyAndOnChange, subtransaction, transaction } from '../../../../../base/common/observable.js';
|
||||
import { commonPrefixLength, firstNonWhitespaceIndex } from '../../../../../base/common/strings.js';
|
||||
import { isDefined } from '../../../../../base/common/types.js';
|
||||
import { IAccessibilityService } from '../../../../../platform/accessibility/common/accessibility.js';
|
||||
@@ -150,11 +150,15 @@ export class InlineCompletionsModel extends Disposable {
|
||||
onlyRequestInlineEdits: false,
|
||||
shouldDebounce: true,
|
||||
provider: undefined as InlineCompletionsProvider | undefined,
|
||||
textChange: false,
|
||||
}),
|
||||
handleChange: (ctx, changeSummary) => {
|
||||
/** @description fetch inline completions */
|
||||
if (ctx.didChange(this._textModelVersionId) && this._preserveCurrentCompletionReasons.has(this._getReason(ctx.change))) {
|
||||
changeSummary.preserveCurrentCompletion = true;
|
||||
if (ctx.didChange(this._textModelVersionId)) {
|
||||
if (this._preserveCurrentCompletionReasons.has(this._getReason(ctx.change))) {
|
||||
changeSummary.preserveCurrentCompletion = true;
|
||||
}
|
||||
changeSummary.textChange = true;
|
||||
} else if (ctx.didChange(this._forceUpdateExplicitlySignal)) {
|
||||
changeSummary.inlineCompletionTriggerKind = InlineCompletionTriggerKind.Explicit;
|
||||
} else if (ctx.didChange(this.dontRefetchSignal)) {
|
||||
@@ -206,7 +210,7 @@ export class InlineCompletionsModel extends Disposable {
|
||||
includeInlineEdits: this._inlineEditsEnabled.read(reader),
|
||||
};
|
||||
|
||||
if (context.triggerKind === InlineCompletionTriggerKind.Automatic) {
|
||||
if (context.triggerKind === InlineCompletionTriggerKind.Automatic && changeSummary.textChange) {
|
||||
if (this.textModel.getAlternativeVersionId() === this._lastShownInlineCompletionInfo?.alternateTextModelVersionId) {
|
||||
// When undoing back to a version where an inline edit/completion was shown,
|
||||
// we want to show an inline edit (or completion) again if it was originally an inline edit (or completion).
|
||||
@@ -572,32 +576,29 @@ export class InlineCompletionsModel extends Disposable {
|
||||
}));
|
||||
|
||||
const inlineCompletionProviders = observableFromEvent(this._languageFeaturesService.inlineCompletionsProvider.onDidChange, () => this._languageFeaturesService.inlineCompletionsProvider.all(textModel));
|
||||
this._register(autorunWithStore((reader, store) => {
|
||||
const providers = inlineCompletionProviders.read(reader);
|
||||
for (const provider of providers) {
|
||||
if (!provider.onDidChangeInlineCompletions) {
|
||||
continue;
|
||||
mapObservableArrayCached(this, inlineCompletionProviders, (provider, store) => {
|
||||
if (!provider.onDidChangeInlineCompletions) {
|
||||
return;
|
||||
}
|
||||
|
||||
store.add(provider.onDidChangeInlineCompletions(() => {
|
||||
if (!this._enabled.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
store.add(provider.onDidChangeInlineCompletions(() => {
|
||||
if (!this._enabled.get()) {
|
||||
return;
|
||||
}
|
||||
// If there is an active suggestion from a different provider, we ignore the update
|
||||
const activeState = this.state.get();
|
||||
if (activeState && (activeState.inlineCompletion || activeState.edits) && activeState.inlineCompletion?.source.provider !== provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is an active suggestion from a different provider, we ignore the update
|
||||
const activeState = this.state.get();
|
||||
if (activeState && (activeState.inlineCompletion || activeState.edits) && activeState.inlineCompletion?.source.provider !== provider) {
|
||||
return;
|
||||
}
|
||||
transaction(tx => {
|
||||
this._fetchSpecificProviderSignal.trigger(tx, provider);
|
||||
this.trigger(tx);
|
||||
});
|
||||
|
||||
transaction(tx => {
|
||||
this._fetchSpecificProviderSignal.trigger(tx, provider);
|
||||
this.trigger(tx);
|
||||
});
|
||||
|
||||
}));
|
||||
}
|
||||
}));
|
||||
}));
|
||||
}).recomputeInitiallyAndOnChange(this._store);
|
||||
|
||||
this._didUndoInlineEdits.recomputeInitiallyAndOnChange(this._store);
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ export class InlineCompletionsSource extends Disposable {
|
||||
|
||||
public fetch(providers: InlineCompletionsProvider[], context: InlineCompletionContextWithoutUuid, activeInlineCompletion: InlineSuggestionIdentity | undefined, withDebounce: boolean, userJumpedToActiveCompletion: IObservable<boolean>, providerhasChangedCompletion: boolean, editorType: InlineCompletionEditorType): Promise<boolean> {
|
||||
const position = this._cursorPosition.get();
|
||||
const request = new UpdateRequest(position, context, this._textModel.getVersionId());
|
||||
const request = new UpdateRequest(position, context, this._textModel.getVersionId(), new Set(providers));
|
||||
|
||||
const target = context.selectedSuggestionInfo ? this.suggestWidgetInlineCompletions.get() : this.inlineCompletions.get();
|
||||
|
||||
@@ -307,6 +307,7 @@ class UpdateRequest {
|
||||
public readonly position: Position,
|
||||
public readonly context: InlineCompletionContextWithoutUuid,
|
||||
public readonly versionId: number,
|
||||
public readonly providers: Set<InlineCompletionsProvider>,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -315,7 +316,8 @@ class UpdateRequest {
|
||||
&& equalsIfDefined(this.context.selectedSuggestionInfo, other.context.selectedSuggestionInfo, itemEquals())
|
||||
&& (other.context.triggerKind === InlineCompletionTriggerKind.Automatic
|
||||
|| this.context.triggerKind === InlineCompletionTriggerKind.Explicit)
|
||||
&& this.versionId === other.versionId;
|
||||
&& this.versionId === other.versionId
|
||||
&& isSubset(other.providers, this.providers);
|
||||
}
|
||||
|
||||
public get isExplicitRequest() {
|
||||
@@ -323,6 +325,10 @@ class UpdateRequest {
|
||||
}
|
||||
}
|
||||
|
||||
function isSubset<T>(set1: Set<T>, set2: Set<T>): boolean {
|
||||
return [...set1].every(item => set2.has(item));
|
||||
}
|
||||
|
||||
class UpdateOperation implements IDisposable {
|
||||
constructor(
|
||||
public readonly request: UpdateRequest,
|
||||
|
||||
@@ -680,13 +680,12 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
|
||||
return `InlineCompletionsProvider(${extensionId})`;
|
||||
},
|
||||
};
|
||||
this._registrations.set(handle, this._languageFeaturesService.inlineCompletionsProvider.register(selector, provider));
|
||||
|
||||
if (typeof eventHandle === 'number') {
|
||||
const emitter = new Emitter<void>();
|
||||
this._registrations.set(eventHandle, emitter);
|
||||
provider.onDidChangeInlineCompletions = emitter.event;
|
||||
}
|
||||
this._registrations.set(handle, this._languageFeaturesService.inlineCompletionsProvider.register(selector, provider));
|
||||
}
|
||||
|
||||
$emitInlineCompletionsChange(handle: number): void {
|
||||
|
||||
Reference in New Issue
Block a user