Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/contrib/suggest/browser/suggestCommitCharacters.ts
4797 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { isNonEmptyArray } from '../../../../base/common/arrays.js';
7
import { DisposableStore } from '../../../../base/common/lifecycle.js';
8
import { ICodeEditor } from '../../../browser/editorBrowser.js';
9
import { EditorOption } from '../../../common/config/editorOptions.js';
10
import { CharacterSet } from '../../../common/core/characterClassifier.js';
11
import { State, SuggestModel } from './suggestModel.js';
12
import { ISelectedSuggestion, SuggestWidget } from './suggestWidget.js';
13
14
export class CommitCharacterController {
15
16
private readonly _disposables = new DisposableStore();
17
18
private _active?: {
19
readonly acceptCharacters: CharacterSet;
20
readonly item: ISelectedSuggestion;
21
};
22
23
constructor(editor: ICodeEditor, widget: SuggestWidget, model: SuggestModel, accept: (selected: ISelectedSuggestion) => unknown) {
24
25
this._disposables.add(model.onDidSuggest(e => {
26
if (e.completionModel.items.length === 0) {
27
this.reset();
28
}
29
}));
30
this._disposables.add(model.onDidCancel(e => {
31
this.reset();
32
}));
33
34
this._disposables.add(widget.onDidShow(() => this._onItem(widget.getFocusedItem())));
35
this._disposables.add(widget.onDidFocus(this._onItem, this));
36
this._disposables.add(widget.onDidHide(this.reset, this));
37
38
this._disposables.add(editor.onWillType(text => {
39
if (this._active && !widget.isFrozen() && model.state !== State.Idle) {
40
const ch = text.charCodeAt(text.length - 1);
41
if (this._active.acceptCharacters.has(ch) && editor.getOption(EditorOption.acceptSuggestionOnCommitCharacter)) {
42
accept(this._active.item);
43
}
44
}
45
}));
46
}
47
48
private _onItem(selected: ISelectedSuggestion | undefined): void {
49
if (!selected || !isNonEmptyArray(selected.item.completion.commitCharacters)) {
50
// no item or no commit characters
51
this.reset();
52
return;
53
}
54
55
if (this._active && this._active.item.item === selected.item) {
56
// still the same item
57
return;
58
}
59
60
// keep item and its commit characters
61
const acceptCharacters = new CharacterSet();
62
for (const ch of selected.item.completion.commitCharacters) {
63
if (ch.length > 0) {
64
acceptCharacters.add(ch.charCodeAt(0));
65
}
66
}
67
this._active = { acceptCharacters, item: selected };
68
}
69
70
reset(): void {
71
this._active = undefined;
72
}
73
74
dispose() {
75
this._disposables.dispose();
76
}
77
}
78
79