Caches ghost text to improve performance.

This commit is contained in:
Henning Dieterichs 2021-07-01 10:42:19 +02:00
parent b314a5fa18
commit 60f21d9525
No known key found for this signature in database
GPG key ID: 771381EFFDB9EC06
3 changed files with 31 additions and 6 deletions

View file

@ -18,21 +18,31 @@ export abstract class DelegatingModel extends Disposable implements GhostTextWid
private readonly onDidChangeEmitter = new Emitter<void>();
public readonly onDidChange = this.onDidChangeEmitter.event;
private hasCachedGhostText = false;
private cachedGhostText: GhostText | undefined;
private readonly currentModelRef = this._register(new MutableDisposable<IReference<GhostTextWidgetModel>>());
protected get targetModel(): GhostTextWidgetModel | undefined {
return this.currentModelRef.value?.object;
}
protected setTargetModel(model: GhostTextWidgetModel | undefined): void {
this.currentModelRef.clear();
this.currentModelRef.value = model ? createDisposableRef(model, model.onDidChange(() => {
this.hasCachedGhostText = false;
this.onDidChangeEmitter.fire();
})) : undefined;
this.hasCachedGhostText = false;
this.onDidChangeEmitter.fire();
}
public get ghostText(): GhostText | undefined {
return this.targetModel?.ghostText;
if (!this.hasCachedGhostText) {
this.cachedGhostText = this.currentModelRef.value?.object?.ghostText;
this.hasCachedGhostText = true;
}
return this.cachedGhostText;
}
public setExpanded(expanded: boolean): void {

View file

@ -75,14 +75,14 @@ export class GhostTextWidget extends Disposable {
}
private update(): void {
if (!this.editor.hasModel() || !this.model.ghostText || this.disposed) {
const ghostText = this.model.ghostText;
if (!this.editor.hasModel() || !ghostText || this.disposed) {
this.partsWidget.clear();
this.additionalLinesWidget.clear();
return;
}
const ghostText = this.model.ghostText;
const inlineTexts = new Array<InsertedInlineText>();
const additionalLines = new Array<LineData>();

View file

@ -20,7 +20,7 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { MutableDisposable } from 'vs/editor/contrib/inlineCompletions/utils';
import { RedoCommand, UndoCommand } from 'vs/editor/browser/editorExtensions';
import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands';
import { stringDiff } from 'vs/base/common/diff/diff';
import { IDiffChange, stringDiff } from 'vs/base/common/diff/diff';
import { GhostTextWidgetModel, GhostText, BaseGhostTextWidgetModel, GhostTextPart } from 'vs/editor/contrib/inlineCompletions/ghostText';
export class InlineCompletionsModel extends Disposable implements GhostTextWidgetModel {
@ -499,7 +499,7 @@ export function inlineCompletionToGhostText(inlineCompletion: NormalizedInlineCo
// This is a single line string
const valueToBeReplaced = textModel.getValueInRange(inlineCompletion.range);
const changes = stringDiff(valueToBeReplaced, inlineCompletion.text, false);
const changes = cachingDiff(valueToBeReplaced, inlineCompletion.text);
const lineNumber = inlineCompletion.range.startLineNumber;
@ -540,6 +540,21 @@ export function inlineCompletionToGhostText(inlineCompletion: NormalizedInlineCo
return new GhostText(lineNumber, parts, 0);
}
let lastRequest: { originalValue: string, newValue: string, changes: IDiffChange[] } | undefined = undefined;
function cachingDiff(originalValue: string, newValue: string): readonly IDiffChange[] {
if (lastRequest?.originalValue === originalValue && lastRequest?.newValue === newValue) {
return lastRequest?.changes;
} else {
const changes = stringDiff(originalValue, newValue, false);
lastRequest = {
originalValue,
newValue,
changes
};
return changes;
}
}
export interface LiveInlineCompletion extends NormalizedInlineCompletion {
sourceProvider: InlineCompletionsProvider;
sourceInlineCompletion: InlineCompletion;