123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- };
- import { createCancelablePromise, RunOnceScheduler } from '../../../base/common/async.js';
- import { onUnexpectedError } from '../../../base/common/errors.js';
- import { MutableDisposable, toDisposable } from '../../../base/common/lifecycle.js';
- import { InlineCompletionTriggerKind } from '../../common/modes.js';
- import { BaseGhostTextWidgetModel, GhostText } from './ghostText.js';
- import { minimizeInlineCompletion, provideInlineCompletions, UpdateOperation } from './inlineCompletionsModel.js';
- import { inlineCompletionToGhostText } from './inlineCompletionToGhostText.js';
- import { SuggestWidgetInlineCompletionProvider } from './suggestWidgetInlineCompletionProvider.js';
- export class SuggestWidgetPreviewModel extends BaseGhostTextWidgetModel {
- constructor(editor, cache) {
- super(editor);
- this.cache = cache;
- this.suggestionInlineCompletionSource = this._register(new SuggestWidgetInlineCompletionProvider(this.editor,
- // Use the first cache item (if any) as preselection.
- () => { var _a, _b; return (_b = (_a = this.cache.value) === null || _a === void 0 ? void 0 : _a.completions[0]) === null || _b === void 0 ? void 0 : _b.toLiveInlineCompletion(); }));
- this.updateOperation = this._register(new MutableDisposable());
- this.updateCacheSoon = this._register(new RunOnceScheduler(() => this.updateCache(), 50));
- this.minReservedLineCount = 0;
- this._register(this.suggestionInlineCompletionSource.onDidChange(() => {
- this.updateCacheSoon.schedule();
- const suggestWidgetState = this.suggestionInlineCompletionSource.state;
- if (!suggestWidgetState) {
- this.minReservedLineCount = 0;
- }
- const newGhostText = this.ghostText;
- if (newGhostText) {
- this.minReservedLineCount = Math.max(this.minReservedLineCount, sum(newGhostText.parts.map(p => p.lines.length - 1)));
- }
- if (this.minReservedLineCount >= 1) {
- this.suggestionInlineCompletionSource.forceRenderingAbove();
- }
- else {
- this.suggestionInlineCompletionSource.stopForceRenderingAbove();
- }
- this.onDidChangeEmitter.fire();
- }));
- this._register(this.cache.onDidChange(() => {
- this.onDidChangeEmitter.fire();
- }));
- this._register(this.editor.onDidChangeCursorPosition((e) => {
- this.minReservedLineCount = 0;
- this.updateCacheSoon.schedule();
- this.onDidChangeEmitter.fire();
- }));
- this._register(toDisposable(() => this.suggestionInlineCompletionSource.stopForceRenderingAbove()));
- }
- get isActive() {
- return this.suggestionInlineCompletionSource.state !== undefined;
- }
- isSuggestionPreviewEnabled() {
- const suggestOptions = this.editor.getOption(105 /* suggest */);
- return suggestOptions.preview;
- }
- updateCache() {
- return __awaiter(this, void 0, void 0, function* () {
- const state = this.suggestionInlineCompletionSource.state;
- if (!state || !state.selectedItem) {
- return;
- }
- const info = {
- text: state.selectedItem.normalizedInlineCompletion.text,
- range: state.selectedItem.normalizedInlineCompletion.range,
- isSnippetText: state.selectedItem.isSnippetText,
- completionKind: state.selectedItem.completionItemKind,
- };
- const position = this.editor.getPosition();
- const promise = createCancelablePromise((token) => __awaiter(this, void 0, void 0, function* () {
- let result;
- try {
- result = yield provideInlineCompletions(position, this.editor.getModel(), { triggerKind: InlineCompletionTriggerKind.Automatic, selectedSuggestionInfo: info }, token);
- }
- catch (e) {
- onUnexpectedError(e);
- return;
- }
- if (token.isCancellationRequested) {
- return;
- }
- this.cache.setValue(this.editor, result, InlineCompletionTriggerKind.Automatic);
- this.onDidChangeEmitter.fire();
- }));
- const operation = new UpdateOperation(promise, InlineCompletionTriggerKind.Automatic);
- this.updateOperation.value = operation;
- yield promise;
- if (this.updateOperation.value === operation) {
- this.updateOperation.clear();
- }
- });
- }
- get ghostText() {
- var _a, _b, _c;
- const isSuggestionPreviewEnabled = this.isSuggestionPreviewEnabled();
- const augmentedCompletion = minimizeInlineCompletion(this.editor.getModel(), (_b = (_a = this.cache.value) === null || _a === void 0 ? void 0 : _a.completions[0]) === null || _b === void 0 ? void 0 : _b.toLiveInlineCompletion());
- const suggestWidgetState = this.suggestionInlineCompletionSource.state;
- const suggestInlineCompletion = minimizeInlineCompletion(this.editor.getModel(), (_c = suggestWidgetState === null || suggestWidgetState === void 0 ? void 0 : suggestWidgetState.selectedItem) === null || _c === void 0 ? void 0 : _c.normalizedInlineCompletion);
- const isAugmentedCompletionValid = augmentedCompletion
- && suggestInlineCompletion
- && augmentedCompletion.text.startsWith(suggestInlineCompletion.text)
- && augmentedCompletion.range.equalsRange(suggestInlineCompletion.range);
- if (!isSuggestionPreviewEnabled && !isAugmentedCompletionValid) {
- return undefined;
- }
- // If the augmented completion is not valid and there is no suggest inline completion, we still show the augmented completion.
- const finalCompletion = isAugmentedCompletionValid ? augmentedCompletion : (suggestInlineCompletion || augmentedCompletion);
- const inlineCompletionPreviewLength = isAugmentedCompletionValid ? finalCompletion.text.length - suggestInlineCompletion.text.length : 0;
- const newGhostText = this.toGhostText(finalCompletion, inlineCompletionPreviewLength);
- return newGhostText;
- }
- toGhostText(completion, inlineCompletionPreviewLength) {
- const mode = this.editor.getOptions().get(105 /* suggest */).previewMode;
- return completion
- ? (inlineCompletionToGhostText(completion, this.editor.getModel(), mode, this.editor.getPosition(), inlineCompletionPreviewLength) ||
- // Show an invisible ghost text to reserve space
- new GhostText(completion.range.endLineNumber, [], this.minReservedLineCount))
- : undefined;
- }
- }
- function sum(arr) {
- return arr.reduce((a, b) => a + b, 0);
- }
|