Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/common/model/bracketPairsTextModelPart/fixBrackets.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 { ILanguageConfigurationService } from '../../languages/languageConfigurationRegistry.js';
7
import { AstNode, AstNodeKind } from './bracketPairsTree/ast.js';
8
import { LanguageAgnosticBracketTokens } from './bracketPairsTree/brackets.js';
9
import { Length, lengthAdd, lengthGetColumnCountIfZeroLineCount, lengthZero } from './bracketPairsTree/length.js';
10
import { parseDocument } from './bracketPairsTree/parser.js';
11
import { DenseKeyProvider } from './bracketPairsTree/smallImmutableSet.js';
12
import { ITokenizerSource, TextBufferTokenizer } from './bracketPairsTree/tokenizer.js';
13
import { IViewLineTokens } from '../../tokens/lineTokens.js';
14
15
export function fixBracketsInLine(tokens: IViewLineTokens, languageConfigurationService: ILanguageConfigurationService): string {
16
const denseKeyProvider = new DenseKeyProvider<string>();
17
const bracketTokens = new LanguageAgnosticBracketTokens(denseKeyProvider, (languageId) =>
18
languageConfigurationService.getLanguageConfiguration(languageId)
19
);
20
const tokenizer = new TextBufferTokenizer(
21
new StaticTokenizerSource([tokens]),
22
bracketTokens
23
);
24
const node = parseDocument(tokenizer, [], undefined, true);
25
26
let str = '';
27
const line = tokens.getLineContent();
28
29
function processNode(node: AstNode, offset: Length) {
30
if (node.kind === AstNodeKind.Pair) {
31
processNode(node.openingBracket, offset);
32
offset = lengthAdd(offset, node.openingBracket.length);
33
34
if (node.child) {
35
processNode(node.child, offset);
36
offset = lengthAdd(offset, node.child.length);
37
}
38
if (node.closingBracket) {
39
processNode(node.closingBracket, offset);
40
offset = lengthAdd(offset, node.closingBracket.length);
41
} else {
42
const singleLangBracketTokens = bracketTokens.getSingleLanguageBracketTokens(node.openingBracket.languageId);
43
44
const closingTokenText = singleLangBracketTokens.findClosingTokenText(node.openingBracket.bracketIds);
45
str += closingTokenText;
46
}
47
} else if (node.kind === AstNodeKind.UnexpectedClosingBracket) {
48
// remove the bracket
49
} else if (node.kind === AstNodeKind.Text || node.kind === AstNodeKind.Bracket) {
50
str += line.substring(
51
lengthGetColumnCountIfZeroLineCount(offset),
52
lengthGetColumnCountIfZeroLineCount(lengthAdd(offset, node.length))
53
);
54
} else if (node.kind === AstNodeKind.List) {
55
for (const child of node.children) {
56
processNode(child, offset);
57
offset = lengthAdd(offset, child.length);
58
}
59
}
60
}
61
62
processNode(node, lengthZero);
63
64
return str;
65
}
66
67
class StaticTokenizerSource implements ITokenizerSource {
68
constructor(private readonly lines: IViewLineTokens[]) { }
69
70
getValue(): string {
71
return this.lines.map(l => l.getLineContent()).join('\n');
72
}
73
getLineCount(): number {
74
return this.lines.length;
75
}
76
getLineLength(lineNumber: number): number {
77
return this.lines[lineNumber - 1].getLineContent().length;
78
}
79
80
tokenization = {
81
getLineTokens: (lineNumber: number): IViewLineTokens => {
82
return this.lines[lineNumber - 1];
83
}
84
};
85
}
86
87