Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/common/languages/supports/electricCharacter.ts
3296 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 { distinct } from '../../../../base/common/arrays.js';
7
import { ScopedLineTokens, ignoreBracketsInToken } from '../supports.js';
8
import { BracketsUtils, RichEditBrackets } from './richEditBrackets.js';
9
10
/**
11
* Interface used to support electric characters
12
* @internal
13
*/
14
export interface IElectricAction {
15
// The line will be indented at the same level of the line
16
// which contains the matching given bracket type.
17
matchOpenBracket: string;
18
}
19
20
export class BracketElectricCharacterSupport {
21
22
private readonly _richEditBrackets: RichEditBrackets | null;
23
24
constructor(richEditBrackets: RichEditBrackets | null) {
25
this._richEditBrackets = richEditBrackets;
26
}
27
28
public getElectricCharacters(): string[] {
29
const result: string[] = [];
30
31
if (this._richEditBrackets) {
32
for (const bracket of this._richEditBrackets.brackets) {
33
for (const close of bracket.close) {
34
const lastChar = close.charAt(close.length - 1);
35
result.push(lastChar);
36
}
37
}
38
}
39
40
return distinct(result);
41
}
42
43
public onElectricCharacter(character: string, context: ScopedLineTokens, column: number): IElectricAction | null {
44
if (!this._richEditBrackets || this._richEditBrackets.brackets.length === 0) {
45
return null;
46
}
47
48
const tokenIndex = context.findTokenIndexAtOffset(column - 1);
49
if (ignoreBracketsInToken(context.getStandardTokenType(tokenIndex))) {
50
return null;
51
}
52
53
const reversedBracketRegex = this._richEditBrackets.reversedRegex;
54
const text = context.getLineContent().substring(0, column - 1) + character;
55
56
const r = BracketsUtils.findPrevBracketInRange(reversedBracketRegex, 1, text, 0, text.length);
57
if (!r) {
58
return null;
59
}
60
61
const bracketText = text.substring(r.startColumn - 1, r.endColumn - 1).toLowerCase();
62
63
const isOpen = this._richEditBrackets.textIsOpenBracket[bracketText];
64
if (isOpen) {
65
return null;
66
}
67
68
const textBeforeBracket = context.getActualLineContentBefore(r.startColumn - 1);
69
if (!/^\s*$/.test(textBeforeBracket)) {
70
// There is other text on the line before the bracket
71
return null;
72
}
73
74
return {
75
matchOpenBracket: bracketText
76
};
77
}
78
}
79
80