Path: blob/main/src/vs/editor/contrib/suggest/browser/suggestCommitCharacters.ts
4797 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { isNonEmptyArray } from '../../../../base/common/arrays.js';6import { DisposableStore } from '../../../../base/common/lifecycle.js';7import { ICodeEditor } from '../../../browser/editorBrowser.js';8import { EditorOption } from '../../../common/config/editorOptions.js';9import { CharacterSet } from '../../../common/core/characterClassifier.js';10import { State, SuggestModel } from './suggestModel.js';11import { ISelectedSuggestion, SuggestWidget } from './suggestWidget.js';1213export class CommitCharacterController {1415private readonly _disposables = new DisposableStore();1617private _active?: {18readonly acceptCharacters: CharacterSet;19readonly item: ISelectedSuggestion;20};2122constructor(editor: ICodeEditor, widget: SuggestWidget, model: SuggestModel, accept: (selected: ISelectedSuggestion) => unknown) {2324this._disposables.add(model.onDidSuggest(e => {25if (e.completionModel.items.length === 0) {26this.reset();27}28}));29this._disposables.add(model.onDidCancel(e => {30this.reset();31}));3233this._disposables.add(widget.onDidShow(() => this._onItem(widget.getFocusedItem())));34this._disposables.add(widget.onDidFocus(this._onItem, this));35this._disposables.add(widget.onDidHide(this.reset, this));3637this._disposables.add(editor.onWillType(text => {38if (this._active && !widget.isFrozen() && model.state !== State.Idle) {39const ch = text.charCodeAt(text.length - 1);40if (this._active.acceptCharacters.has(ch) && editor.getOption(EditorOption.acceptSuggestionOnCommitCharacter)) {41accept(this._active.item);42}43}44}));45}4647private _onItem(selected: ISelectedSuggestion | undefined): void {48if (!selected || !isNonEmptyArray(selected.item.completion.commitCharacters)) {49// no item or no commit characters50this.reset();51return;52}5354if (this._active && this._active.item.item === selected.item) {55// still the same item56return;57}5859// keep item and its commit characters60const acceptCharacters = new CharacterSet();61for (const ch of selected.item.completion.commitCharacters) {62if (ch.length > 0) {63acceptCharacters.add(ch.charCodeAt(0));64}65}66this._active = { acceptCharacters, item: selected };67}6869reset(): void {70this._active = undefined;71}7273dispose() {74this._disposables.dispose();75}76}777879