monaco-editor-core
Version:
A browser based code editor
665 lines (664 loc) • 31.7 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var SuggestModel_1;
import { TimeoutTimer } from '../../../../base/common/async.js';
import { CancellationTokenSource } from '../../../../base/common/cancellation.js';
import { onUnexpectedError } from '../../../../base/common/errors.js';
import { Emitter } from '../../../../base/common/event.js';
import { DisposableStore, dispose } from '../../../../base/common/lifecycle.js';
import { getLeadingWhitespace, isHighSurrogate, isLowSurrogate } from '../../../../base/common/strings.js';
import { Selection } from '../../../common/core/selection.js';
import { IEditorWorkerService } from '../../../common/services/editorWorker.js';
import { WordDistance } from './wordDistance.js';
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
import { ILogService } from '../../../../platform/log/common/log.js';
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
import { CompletionModel } from './completionModel.js';
import { CompletionOptions, getSnippetSuggestSupport, provideSuggestionItems, QuickSuggestionsOptions } from './suggest.js';
import { ILanguageFeaturesService } from '../../../common/services/languageFeatures.js';
import { FuzzyScoreOptions } from '../../../../base/common/filters.js';
import { assertType } from '../../../../base/common/types.js';
import { InlineCompletionContextKeys } from '../../inlineCompletions/browser/controller/inlineCompletionContextKeys.js';
import { SnippetController2 } from '../../snippet/browser/snippetController2.js';
import { IEnvironmentService } from '../../../../platform/environment/common/environment.js';
export class LineContext {
static shouldAutoTrigger(editor) {
if (!editor.hasModel()) {
return false;
}
const model = editor.getModel();
const pos = editor.getPosition();
model.tokenization.tokenizeIfCheap(pos.lineNumber);
const word = model.getWordAtPosition(pos);
if (!word) {
return false;
}
if (word.endColumn !== pos.column &&
word.startColumn + 1 !== pos.column /* after typing a single character before a word */) {
return false;
}
if (!isNaN(Number(word.word))) {
return false;
}
return true;
}
constructor(model, position, triggerOptions) {
this.leadingLineContent = model.getLineContent(position.lineNumber).substr(0, position.column - 1);
this.leadingWord = model.getWordUntilPosition(position);
this.lineNumber = position.lineNumber;
this.column = position.column;
this.triggerOptions = triggerOptions;
}
}
function canShowQuickSuggest(editor, contextKeyService, configurationService) {
if (!Boolean(contextKeyService.getContextKeyValue(InlineCompletionContextKeys.inlineSuggestionVisible.key))) {
// Allow if there is no inline suggestion.
return true;
}
const suppressSuggestions = contextKeyService.getContextKeyValue(InlineCompletionContextKeys.suppressSuggestions.key);
if (suppressSuggestions !== undefined) {
return !suppressSuggestions;
}
return !editor.getOption(62 /* EditorOption.inlineSuggest */).suppressSuggestions;
}
function canShowSuggestOnTriggerCharacters(editor, contextKeyService, configurationService) {
if (!Boolean(contextKeyService.getContextKeyValue('inlineSuggestionVisible'))) {
// Allow if there is no inline suggestion.
return true;
}
const suppressSuggestions = contextKeyService.getContextKeyValue(InlineCompletionContextKeys.suppressSuggestions.key);
if (suppressSuggestions !== undefined) {
return !suppressSuggestions;
}
return !editor.getOption(62 /* EditorOption.inlineSuggest */).suppressSuggestions;
}
let SuggestModel = SuggestModel_1 = class SuggestModel {
constructor(_editor, _editorWorkerService, _clipboardService, _telemetryService, _logService, _contextKeyService, _configurationService, _languageFeaturesService, _envService) {
this._editor = _editor;
this._editorWorkerService = _editorWorkerService;
this._clipboardService = _clipboardService;
this._telemetryService = _telemetryService;
this._logService = _logService;
this._contextKeyService = _contextKeyService;
this._configurationService = _configurationService;
this._languageFeaturesService = _languageFeaturesService;
this._envService = _envService;
this._toDispose = new DisposableStore();
this._triggerCharacterListener = new DisposableStore();
this._triggerQuickSuggest = new TimeoutTimer();
this._triggerState = undefined;
this._completionDisposables = new DisposableStore();
this._onDidCancel = new Emitter();
this._onDidTrigger = new Emitter();
this._onDidSuggest = new Emitter();
this.onDidCancel = this._onDidCancel.event;
this.onDidTrigger = this._onDidTrigger.event;
this.onDidSuggest = this._onDidSuggest.event;
this._telemetryGate = 0;
this._currentSelection = this._editor.getSelection() || new Selection(1, 1, 1, 1);
// wire up various listeners
this._toDispose.add(this._editor.onDidChangeModel(() => {
this._updateTriggerCharacters();
this.cancel();
}));
this._toDispose.add(this._editor.onDidChangeModelLanguage(() => {
this._updateTriggerCharacters();
this.cancel();
}));
this._toDispose.add(this._editor.onDidChangeConfiguration(() => {
this._updateTriggerCharacters();
}));
this._toDispose.add(this._languageFeaturesService.completionProvider.onDidChange(() => {
this._updateTriggerCharacters();
this._updateActiveSuggestSession();
}));
let editorIsComposing = false;
this._toDispose.add(this._editor.onDidCompositionStart(() => {
editorIsComposing = true;
}));
this._toDispose.add(this._editor.onDidCompositionEnd(() => {
editorIsComposing = false;
this._onCompositionEnd();
}));
this._toDispose.add(this._editor.onDidChangeCursorSelection(e => {
// only trigger suggest when the editor isn't composing a character
if (!editorIsComposing) {
this._onCursorChange(e);
}
}));
this._toDispose.add(this._editor.onDidChangeModelContent(() => {
// only filter completions when the editor isn't composing a character
// allow-any-unicode-next-line
// e.g. ¨ + u makes ü but just ¨ cannot be used for filtering
if (!editorIsComposing && this._triggerState !== undefined) {
this._refilterCompletionItems();
}
}));
this._updateTriggerCharacters();
}
dispose() {
dispose(this._triggerCharacterListener);
dispose([this._onDidCancel, this._onDidSuggest, this._onDidTrigger, this._triggerQuickSuggest]);
this._toDispose.dispose();
this._completionDisposables.dispose();
this.cancel();
}
_updateTriggerCharacters() {
this._triggerCharacterListener.clear();
if (this._editor.getOption(92 /* EditorOption.readOnly */)
|| !this._editor.hasModel()
|| !this._editor.getOption(122 /* EditorOption.suggestOnTriggerCharacters */)) {
return;
}
const supportsByTriggerCharacter = new Map();
for (const support of this._languageFeaturesService.completionProvider.all(this._editor.getModel())) {
for (const ch of support.triggerCharacters || []) {
let set = supportsByTriggerCharacter.get(ch);
if (!set) {
set = new Set();
const suggestSupport = getSnippetSuggestSupport();
if (suggestSupport) {
set.add(suggestSupport);
}
supportsByTriggerCharacter.set(ch, set);
}
set.add(support);
}
}
const checkTriggerCharacter = (text) => {
if (!canShowSuggestOnTriggerCharacters(this._editor, this._contextKeyService, this._configurationService)) {
return;
}
if (LineContext.shouldAutoTrigger(this._editor)) {
// don't trigger by trigger characters when this is a case for quick suggest
return;
}
if (!text) {
// came here from the compositionEnd-event
const position = this._editor.getPosition();
const model = this._editor.getModel();
text = model.getLineContent(position.lineNumber).substr(0, position.column - 1);
}
let lastChar = '';
if (isLowSurrogate(text.charCodeAt(text.length - 1))) {
if (isHighSurrogate(text.charCodeAt(text.length - 2))) {
lastChar = text.substr(text.length - 2);
}
}
else {
lastChar = text.charAt(text.length - 1);
}
const supports = supportsByTriggerCharacter.get(lastChar);
if (supports) {
// keep existing items that where not computed by the
// supports/providers that want to trigger now
const providerItemsToReuse = new Map();
if (this._completionModel) {
for (const [provider, items] of this._completionModel.getItemsByProvider()) {
if (!supports.has(provider)) {
providerItemsToReuse.set(provider, items);
}
}
}
this.trigger({
auto: true,
triggerKind: 1 /* CompletionTriggerKind.TriggerCharacter */,
triggerCharacter: lastChar,
retrigger: Boolean(this._completionModel),
clipboardText: this._completionModel?.clipboardText,
completionOptions: { providerFilter: supports, providerItemsToReuse }
});
}
};
this._triggerCharacterListener.add(this._editor.onDidType(checkTriggerCharacter));
this._triggerCharacterListener.add(this._editor.onDidCompositionEnd(() => checkTriggerCharacter()));
}
// --- trigger/retrigger/cancel suggest
get state() {
if (!this._triggerState) {
return 0 /* State.Idle */;
}
else if (!this._triggerState.auto) {
return 1 /* State.Manual */;
}
else {
return 2 /* State.Auto */;
}
}
cancel(retrigger = false) {
if (this._triggerState !== undefined) {
this._triggerQuickSuggest.cancel();
this._requestToken?.cancel();
this._requestToken = undefined;
this._triggerState = undefined;
this._completionModel = undefined;
this._context = undefined;
this._onDidCancel.fire({ retrigger });
}
}
clear() {
this._completionDisposables.clear();
}
_updateActiveSuggestSession() {
if (this._triggerState !== undefined) {
if (!this._editor.hasModel() || !this._languageFeaturesService.completionProvider.has(this._editor.getModel())) {
this.cancel();
}
else {
this.trigger({ auto: this._triggerState.auto, retrigger: true });
}
}
}
_onCursorChange(e) {
if (!this._editor.hasModel()) {
return;
}
const prevSelection = this._currentSelection;
this._currentSelection = this._editor.getSelection();
if (!e.selection.isEmpty()
|| (e.reason !== 0 /* CursorChangeReason.NotSet */ && e.reason !== 3 /* CursorChangeReason.Explicit */)
|| (e.source !== 'keyboard' && e.source !== 'deleteLeft')) {
// Early exit if nothing needs to be done!
// Leave some form of early exit check here if you wish to continue being a cursor position change listener ;)
this.cancel();
return;
}
if (this._triggerState === undefined && e.reason === 0 /* CursorChangeReason.NotSet */) {
if (prevSelection.containsRange(this._currentSelection) || prevSelection.getEndPosition().isBeforeOrEqual(this._currentSelection.getPosition())) {
// cursor did move RIGHT due to typing -> trigger quick suggest
this._doTriggerQuickSuggest();
}
}
else if (this._triggerState !== undefined && e.reason === 3 /* CursorChangeReason.Explicit */) {
// suggest is active and something like cursor keys are used to move
// the cursor. this means we can refilter at the new position
this._refilterCompletionItems();
}
}
_onCompositionEnd() {
// trigger or refilter when composition ends
if (this._triggerState === undefined) {
this._doTriggerQuickSuggest();
}
else {
this._refilterCompletionItems();
}
}
_doTriggerQuickSuggest() {
if (QuickSuggestionsOptions.isAllOff(this._editor.getOption(90 /* EditorOption.quickSuggestions */))) {
// not enabled
return;
}
if (this._editor.getOption(119 /* EditorOption.suggest */).snippetsPreventQuickSuggestions && SnippetController2.get(this._editor)?.isInSnippet()) {
// no quick suggestion when in snippet mode
return;
}
this.cancel();
this._triggerQuickSuggest.cancelAndSet(() => {
if (this._triggerState !== undefined) {
return;
}
if (!LineContext.shouldAutoTrigger(this._editor)) {
return;
}
if (!this._editor.hasModel() || !this._editor.hasWidgetFocus()) {
return;
}
const model = this._editor.getModel();
const pos = this._editor.getPosition();
// validate enabled now
const config = this._editor.getOption(90 /* EditorOption.quickSuggestions */);
if (QuickSuggestionsOptions.isAllOff(config)) {
return;
}
if (!QuickSuggestionsOptions.isAllOn(config)) {
// Check the type of the token that triggered this
model.tokenization.tokenizeIfCheap(pos.lineNumber);
const lineTokens = model.tokenization.getLineTokens(pos.lineNumber);
const tokenType = lineTokens.getStandardTokenType(lineTokens.findTokenIndexAtOffset(Math.max(pos.column - 1 - 1, 0)));
if (QuickSuggestionsOptions.valueFor(config, tokenType) !== 'on') {
return;
}
}
if (!canShowQuickSuggest(this._editor, this._contextKeyService, this._configurationService)) {
// do not trigger quick suggestions if inline suggestions are shown
return;
}
if (!this._languageFeaturesService.completionProvider.has(model)) {
return;
}
// we made it till here -> trigger now
this.trigger({ auto: true });
}, this._editor.getOption(91 /* EditorOption.quickSuggestionsDelay */));
}
_refilterCompletionItems() {
assertType(this._editor.hasModel());
assertType(this._triggerState !== undefined);
const model = this._editor.getModel();
const position = this._editor.getPosition();
const ctx = new LineContext(model, position, { ...this._triggerState, refilter: true });
this._onNewContext(ctx);
}
trigger(options) {
if (!this._editor.hasModel()) {
return;
}
const model = this._editor.getModel();
const ctx = new LineContext(model, this._editor.getPosition(), options);
// Cancel previous requests, change state & update UI
this.cancel(options.retrigger);
this._triggerState = options;
this._onDidTrigger.fire({ auto: options.auto, shy: options.shy ?? false, position: this._editor.getPosition() });
// Capture context when request was sent
this._context = ctx;
// Build context for request
let suggestCtx = { triggerKind: options.triggerKind ?? 0 /* CompletionTriggerKind.Invoke */ };
if (options.triggerCharacter) {
suggestCtx = {
triggerKind: 1 /* CompletionTriggerKind.TriggerCharacter */,
triggerCharacter: options.triggerCharacter
};
}
this._requestToken = new CancellationTokenSource();
// kind filter and snippet sort rules
const snippetSuggestions = this._editor.getOption(113 /* EditorOption.snippetSuggestions */);
let snippetSortOrder = 1 /* SnippetSortOrder.Inline */;
switch (snippetSuggestions) {
case 'top':
snippetSortOrder = 0 /* SnippetSortOrder.Top */;
break;
// ↓ that's the default anyways...
// case 'inline':
// snippetSortOrder = SnippetSortOrder.Inline;
// break;
case 'bottom':
snippetSortOrder = 2 /* SnippetSortOrder.Bottom */;
break;
}
const { itemKind: itemKindFilter, showDeprecated } = SuggestModel_1.createSuggestFilter(this._editor);
const completionOptions = new CompletionOptions(snippetSortOrder, options.completionOptions?.kindFilter ?? itemKindFilter, options.completionOptions?.providerFilter, options.completionOptions?.providerItemsToReuse, showDeprecated);
const wordDistance = WordDistance.create(this._editorWorkerService, this._editor);
const completions = provideSuggestionItems(this._languageFeaturesService.completionProvider, model, this._editor.getPosition(), completionOptions, suggestCtx, this._requestToken.token);
Promise.all([completions, wordDistance]).then(async ([completions, wordDistance]) => {
this._requestToken?.dispose();
if (!this._editor.hasModel()) {
return;
}
let clipboardText = options?.clipboardText;
if (!clipboardText && completions.needsClipboard) {
clipboardText = await this._clipboardService.readText();
}
if (this._triggerState === undefined) {
return;
}
const model = this._editor.getModel();
// const items = completions.items;
// if (existing) {
// const cmpFn = getSuggestionComparator(snippetSortOrder);
// items = items.concat(existing.items).sort(cmpFn);
// }
const ctx = new LineContext(model, this._editor.getPosition(), options);
const fuzzySearchOptions = {
...FuzzyScoreOptions.default,
firstMatchCanBeWeak: !this._editor.getOption(119 /* EditorOption.suggest */).matchOnWordStartOnly
};
this._completionModel = new CompletionModel(completions.items, this._context.column, {
leadingLineContent: ctx.leadingLineContent,
characterCountDelta: ctx.column - this._context.column
}, wordDistance, this._editor.getOption(119 /* EditorOption.suggest */), this._editor.getOption(113 /* EditorOption.snippetSuggestions */), fuzzySearchOptions, clipboardText);
// store containers so that they can be disposed later
this._completionDisposables.add(completions.disposable);
this._onNewContext(ctx);
// finally report telemetry about durations
this._reportDurationsTelemetry(completions.durations);
// report invalid completions by source
if (!this._envService.isBuilt || this._envService.isExtensionDevelopment) {
for (const item of completions.items) {
if (item.isInvalid) {
this._logService.warn(`[suggest] did IGNORE invalid completion item from ${item.provider._debugDisplayName}`, item.completion);
}
}
}
}).catch(onUnexpectedError);
}
_reportDurationsTelemetry(durations) {
if (this._telemetryGate++ % 230 !== 0) {
return;
}
setTimeout(() => {
this._telemetryService.publicLog2('suggest.durations.json', { data: JSON.stringify(durations) });
this._logService.debug('suggest.durations.json', durations);
});
}
static createSuggestFilter(editor) {
// kind filter and snippet sort rules
const result = new Set();
// snippet setting
const snippetSuggestions = editor.getOption(113 /* EditorOption.snippetSuggestions */);
if (snippetSuggestions === 'none') {
result.add(27 /* CompletionItemKind.Snippet */);
}
// type setting
const suggestOptions = editor.getOption(119 /* EditorOption.suggest */);
if (!suggestOptions.showMethods) {
result.add(0 /* CompletionItemKind.Method */);
}
if (!suggestOptions.showFunctions) {
result.add(1 /* CompletionItemKind.Function */);
}
if (!suggestOptions.showConstructors) {
result.add(2 /* CompletionItemKind.Constructor */);
}
if (!suggestOptions.showFields) {
result.add(3 /* CompletionItemKind.Field */);
}
if (!suggestOptions.showVariables) {
result.add(4 /* CompletionItemKind.Variable */);
}
if (!suggestOptions.showClasses) {
result.add(5 /* CompletionItemKind.Class */);
}
if (!suggestOptions.showStructs) {
result.add(6 /* CompletionItemKind.Struct */);
}
if (!suggestOptions.showInterfaces) {
result.add(7 /* CompletionItemKind.Interface */);
}
if (!suggestOptions.showModules) {
result.add(8 /* CompletionItemKind.Module */);
}
if (!suggestOptions.showProperties) {
result.add(9 /* CompletionItemKind.Property */);
}
if (!suggestOptions.showEvents) {
result.add(10 /* CompletionItemKind.Event */);
}
if (!suggestOptions.showOperators) {
result.add(11 /* CompletionItemKind.Operator */);
}
if (!suggestOptions.showUnits) {
result.add(12 /* CompletionItemKind.Unit */);
}
if (!suggestOptions.showValues) {
result.add(13 /* CompletionItemKind.Value */);
}
if (!suggestOptions.showConstants) {
result.add(14 /* CompletionItemKind.Constant */);
}
if (!suggestOptions.showEnums) {
result.add(15 /* CompletionItemKind.Enum */);
}
if (!suggestOptions.showEnumMembers) {
result.add(16 /* CompletionItemKind.EnumMember */);
}
if (!suggestOptions.showKeywords) {
result.add(17 /* CompletionItemKind.Keyword */);
}
if (!suggestOptions.showWords) {
result.add(18 /* CompletionItemKind.Text */);
}
if (!suggestOptions.showColors) {
result.add(19 /* CompletionItemKind.Color */);
}
if (!suggestOptions.showFiles) {
result.add(20 /* CompletionItemKind.File */);
}
if (!suggestOptions.showReferences) {
result.add(21 /* CompletionItemKind.Reference */);
}
if (!suggestOptions.showColors) {
result.add(22 /* CompletionItemKind.Customcolor */);
}
if (!suggestOptions.showFolders) {
result.add(23 /* CompletionItemKind.Folder */);
}
if (!suggestOptions.showTypeParameters) {
result.add(24 /* CompletionItemKind.TypeParameter */);
}
if (!suggestOptions.showSnippets) {
result.add(27 /* CompletionItemKind.Snippet */);
}
if (!suggestOptions.showUsers) {
result.add(25 /* CompletionItemKind.User */);
}
if (!suggestOptions.showIssues) {
result.add(26 /* CompletionItemKind.Issue */);
}
return { itemKind: result, showDeprecated: suggestOptions.showDeprecated };
}
_onNewContext(ctx) {
if (!this._context) {
// happens when 24x7 IntelliSense is enabled and still in its delay
return;
}
if (ctx.lineNumber !== this._context.lineNumber) {
// e.g. happens when pressing Enter while IntelliSense is computed
this.cancel();
return;
}
if (getLeadingWhitespace(ctx.leadingLineContent) !== getLeadingWhitespace(this._context.leadingLineContent)) {
// cancel IntelliSense when line start changes
// happens when the current word gets outdented
this.cancel();
return;
}
if (ctx.column < this._context.column) {
// typed -> moved cursor LEFT -> retrigger if still on a word
if (ctx.leadingWord.word) {
this.trigger({ auto: this._context.triggerOptions.auto, retrigger: true });
}
else {
this.cancel();
}
return;
}
if (!this._completionModel) {
// happens when IntelliSense is not yet computed
return;
}
if (ctx.leadingWord.word.length !== 0 && ctx.leadingWord.startColumn > this._context.leadingWord.startColumn) {
// started a new word while IntelliSense shows -> retrigger but reuse all items that we currently have
const shouldAutoTrigger = LineContext.shouldAutoTrigger(this._editor);
if (shouldAutoTrigger && this._context) {
// shouldAutoTrigger forces tokenization, which can cause pending cursor change events to be emitted, which can cause
// suggestions to be cancelled, which causes `this._context` to be undefined
const map = this._completionModel.getItemsByProvider();
this.trigger({
auto: this._context.triggerOptions.auto,
retrigger: true,
clipboardText: this._completionModel.clipboardText,
completionOptions: { providerItemsToReuse: map }
});
}
return;
}
if (ctx.column > this._context.column && this._completionModel.getIncompleteProvider().size > 0 && ctx.leadingWord.word.length !== 0) {
// typed -> moved cursor RIGHT & incomple model & still on a word -> retrigger
const providerItemsToReuse = new Map();
const providerFilter = new Set();
for (const [provider, items] of this._completionModel.getItemsByProvider()) {
if (items.length > 0 && items[0].container.incomplete) {
providerFilter.add(provider);
}
else {
providerItemsToReuse.set(provider, items);
}
}
this.trigger({
auto: this._context.triggerOptions.auto,
triggerKind: 2 /* CompletionTriggerKind.TriggerForIncompleteCompletions */,
retrigger: true,
clipboardText: this._completionModel.clipboardText,
completionOptions: { providerFilter, providerItemsToReuse }
});
}
else {
// typed -> moved cursor RIGHT -> update UI
const oldLineContext = this._completionModel.lineContext;
let isFrozen = false;
this._completionModel.lineContext = {
leadingLineContent: ctx.leadingLineContent,
characterCountDelta: ctx.column - this._context.column
};
if (this._completionModel.items.length === 0) {
const shouldAutoTrigger = LineContext.shouldAutoTrigger(this._editor);
if (!this._context) {
// shouldAutoTrigger forces tokenization, which can cause pending cursor change events to be emitted, which can cause
// suggestions to be cancelled, which causes `this._context` to be undefined
this.cancel();
return;
}
if (shouldAutoTrigger && this._context.leadingWord.endColumn < ctx.leadingWord.startColumn) {
// retrigger when heading into a new word
this.trigger({ auto: this._context.triggerOptions.auto, retrigger: true });
return;
}
if (!this._context.triggerOptions.auto) {
// freeze when IntelliSense was manually requested
this._completionModel.lineContext = oldLineContext;
isFrozen = this._completionModel.items.length > 0;
if (isFrozen && ctx.leadingWord.word.length === 0) {
// there were results before but now there aren't
// and also we are not on a word anymore -> cancel
this.cancel();
return;
}
}
else {
// nothing left
this.cancel();
return;
}
}
this._onDidSuggest.fire({
completionModel: this._completionModel,
triggerOptions: ctx.triggerOptions,
isFrozen,
});
}
}
};
SuggestModel = SuggestModel_1 = __decorate([
__param(1, IEditorWorkerService),
__param(2, IClipboardService),
__param(3, ITelemetryService),
__param(4, ILogService),
__param(5, IContextKeyService),
__param(6, IConfigurationService),
__param(7, ILanguageFeaturesService),
__param(8, IEnvironmentService)
], SuggestModel);
export { SuggestModel };