This commit is contained in:
Henning Dieterichs
2021-06-03 22:44:32 +02:00
parent f73f263c6b
commit 0a5d652bdf
2 changed files with 64 additions and 3 deletions
@@ -7,7 +7,7 @@ import { CancelablePromise, createCancelablePromise, RunOnceScheduler } from 'vs
import { CancellationToken } from 'vs/base/common/cancellation';
import { onUnexpectedError, onUnexpectedExternalError } from 'vs/base/common/errors';
import { Emitter } from 'vs/base/common/event';
import { Disposable, IDisposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import * as strings from 'vs/base/common/strings';
import { IActiveCodeEditor } from 'vs/editor/browser/editorBrowser';
import { Position } from 'vs/editor/common/core/position';
@@ -18,6 +18,7 @@ import { BaseGhostTextWidgetModel, GhostText, GhostTextWidgetModel } from 'vs/ed
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { MutableDisposable } from 'vs/editor/contrib/inlineCompletions/utils';
export class InlineCompletionsModel extends Disposable implements GhostTextWidgetModel {
protected readonly onDidChangeEmitter = new Emitter<void>();
@@ -120,6 +121,7 @@ export class InlineCompletionsModel extends Disposable implements GhostTextWidge
}
public commitCurrentSuggestion(): void {
// Don't dispose the session, so that after committing, more suggestions are shown.
this.session?.commitCurrentCompletion();
}
@@ -339,7 +341,10 @@ class InlineCompletionsSession extends BaseGhostTextWidgetModel {
}
public commit(completion: LiveInlineCompletion): void {
this.cache.clear();
// Mark the cache as stale, but don't dispose it yet,
// otherwise command args might get disposed.
const cache = this.cache.replace(undefined);
this.editor.executeEdits(
'inlineCompletions.accept',
[
@@ -347,7 +352,12 @@ class InlineCompletionsSession extends BaseGhostTextWidgetModel {
]
);
if (completion.command) {
this.commandService.executeCommand(completion.command.id, ...(completion.command.arguments || [])).then(undefined, onUnexpectedExternalError);
this.commandService
.executeCommand(completion.command.id, ...(completion.command.arguments || []))
.finally(() => {
cache?.dispose();
})
.then(undefined, onUnexpectedExternalError);
}
this.onDidChangeEmitter.fire();
@@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IDisposable, trackDisposable } from 'vs/base/common/lifecycle';
// TODO: merge this class into Matt's MutableDisposable.
/**
* Manages the lifecycle of a disposable value that may be changed.
*
* This ensures that when the disposable value is changed, the previously held disposable is disposed of. You can
* also register a `MutableDisposable` on a `Disposable` to ensure it is automatically cleaned up.
*/
export class MutableDisposable<T extends IDisposable> implements IDisposable {
private _value?: T;
private _isDisposed = false;
constructor() {
trackDisposable(this);
}
get value(): T | undefined {
return this._isDisposed ? undefined : this._value;
}
set value(value: T | undefined) {
if (this._isDisposed || value === this._value) {
return;
}
this._value?.dispose();
this._value = value;
}
clear() {
this.value = undefined;
}
dispose(): void {
this._isDisposed = true;
this._value?.dispose();
this._value = undefined;
}
replace(newValue: T | undefined): T | undefined {
const oldValue = this._value;
this._value = newValue;
return oldValue;
}
}