languageConfiguration.ts ×7

Frontier kind: Code frontier

unlabeled · c_7dc9f5f9b382

890 tests · 5603 LOC · 29 files · introduces 0 tests · 330 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
7 ranges330 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
763 ranges5603 lines · 29 files · Browse complete extent
All tests (intent)
890 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 330 introduced LOC across 7 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/editor/common/languages/languageConfiguration.ts 330 introduced LOC · 7 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- languageConfiguration.ts
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 { CharCode } from '../../../base/common/charCode.js';
7 > import { StandardTokenType } from '../encodedTokenAttributes.js';
8 > import { ScopedLineTokens } from './supports.js';
9 >
10 > /**
11 > * Configuration for line comments.
12 > */
13 > export interface LineCommentConfig {
14 > /**
15 > * The line comment token, like `//`
16 > */
17 > comment: string;
18 > /**
19 > * Whether the comment token should not be indented and placed at the first column.
20 > * Defaults to false.
21 > */
22 > noIndent?: boolean;
23 > }
24 >
25 > /**
26 > * Describes how comments for a language work.
27 > */
28 > export interface CommentRule {
29 > /**
30 > * The line comment token, like `// this is a comment`.
31 > * Can be a string or an object with comment and optional noIndent properties.
32 > */
33 > lineComment?: string | LineCommentConfig | null;
34 > /**
35 > * The block comment character pair, like `/* block comment */`
36 > */
37 > blockComment?: CharacterPair | null;
38 > }
39 >
40 > /**
41 > * The language configuration interface defines the contract between extensions and
42 > * various editor features, like automatic bracket insertion, automatic indentation etc.
43 > */
44 > export interface LanguageConfiguration {
45 > /**
46 > * The language's comment settings.
47 > */
48 > comments?: CommentRule;
49 > /**
50 > * The language's brackets.
51 > * This configuration implicitly affects pressing Enter around these brackets.
52 > */
53 > brackets?: CharacterPair[];
54 > /**
55 > * The language's word definition.
56 > * If the language supports Unicode identifiers (e.g. JavaScript), it is preferable
57 > * to provide a word definition that uses exclusion of known separators.
58 > * e.g.: A regex that matches anything except known separators (and dot is allowed to occur in a floating point number):
59 > * /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g
60 > */
61 > wordPattern?: RegExp;
62 > /**
63 > * The language's indentation settings.
64 > */
65 > indentationRules?: IndentationRule;
66 > /**
67 > * The language's rules to be evaluated when pressing Enter.
68 > */
69 > onEnterRules?: OnEnterRule[];
70 > /**
71 > * The language's auto closing pairs. The 'close' character is automatically inserted with the
72 > * 'open' character is typed. If not set, the configured brackets will be used.
73 > */
74 > autoClosingPairs?: IAutoClosingPairConditional[];
75 > /**
76 > * The language's surrounding pairs. When the 'open' character is typed on a selection, the
77 > * selected string is surrounded by the open and close characters. If not set, the autoclosing pairs
78 > * settings will be used.
79 > */
80 > surroundingPairs?: IAutoClosingPair[];
81 > /**
82 > * Defines a list of bracket pairs that are colorized depending on their nesting level.
83 > * If not set, the configured brackets will be used.
84 > */
85 > colorizedBracketPairs?: CharacterPair[];
86 > /**
87 > * Defines what characters must be after the cursor for bracket or quote autoclosing to occur when using the \'languageDefined\' autoclosing setting.
88 > *
89 > * This is typically the set of characters which can not start an expression, such as whitespace, closing brackets, non-unary operators, etc.
90 > */
91 > autoCloseBefore?: string;
92 >
93 > /**
94 > * The language's folding rules.
95 > */
96 > folding?: FoldingRules;
97 >
98 > /**
99 > * **Deprecated** Do not use.
100 > *
101 > * @deprecated Will be replaced by a better API soon.
102 > */
103 > __electricCharacterSupport?: {
104 > docComment?: IDocComment;
105 > };
106 > }
107 >
108 > /**
109 > * @internal
110 > */
111 > type OrUndefined<T> = { [P in keyof T]: T[P] | undefined };
112 >
113 > /**
114 > * @internal
115 > */
116 > export type ExplicitLanguageConfiguration = OrUndefined<Required<LanguageConfiguration>>;
117 >
118 > /**
119 > * Describes indentation rules for a language.
120 > */
121 > export interface IndentationRule {
122 > /**
123 > * If a line matches this pattern, then all the lines after it should be unindented once (until another rule matches).
124 > */
125 > decreaseIndentPattern: RegExp;
126 > /**
127 > * If a line matches this pattern, then all the lines after it should be indented once (until another rule matches).
128 > */
129 > increaseIndentPattern: RegExp;
130 > /**
131 > * If a line matches this pattern, then **only the next line** after it should be indented once.
132 > */
133 > indentNextLinePattern?: RegExp | null;
134 > /**
135 > * If a line matches this pattern, then its indentation should not be changed and it should not be evaluated against the other rules.
136 > */
137 > unIndentedLinePattern?: RegExp | null;
138 >
139 > }
140 >
141 > /**
142 > * Describes language specific folding markers such as '#region' and '#endregion'.
143 > * The start and end regexes will be tested against the contents of all lines and must be designed efficiently:
144 > * - the regex should start with '^'
145 > */
146 > export interface FoldingMarkers {
147 > start: RegExp;
148 > end: RegExp;
149 > }
150 >
151 > /**
152 > * Describes folding rules for a language.
153 > */
154 > export interface FoldingRules {
155 > /**
156 > * Used by the indentation based strategy to decide whether empty lines belong to the previous or the next block.
157 > * A language adheres to the off-side rule if blocks in that language are expressed by their indentation.
158 > * See [wikipedia](https://en.wikipedia.org/wiki/Off-side_rule) for more information.
159 > * If not set, `false` is used and empty lines belong to the previous block.
160 > */
161 > offSide?: boolean;
162 >
163 > /**
164 > * Region markers used by the language.
165 > */
166 > markers?: FoldingMarkers;
167 > }
168 >
169 > /**
170 > * Describes a rule to be evaluated when pressing Enter.
171 > */
172 > export interface OnEnterRule {
173 > /**
174 > * This rule will only execute if the text before the cursor matches this regular expression.
175 > */
176 > beforeText: RegExp;
177 > /**
178 > * This rule will only execute if the text after the cursor matches this regular expression.
179 > */
180 > afterText?: RegExp;
181 > /**
182 > * This rule will only execute if the text above the this line matches this regular expression.
183 > */
184 > previousLineText?: RegExp;
185 > /**
186 > * The action to execute.
187 > */
188 > action: EnterAction;
189 > }
190 >
191 > /**
192 > * Definition of documentation comments (e.g. Javadoc/JSdoc)
193 > */
194 > export interface IDocComment {
195 > /**
196 > * The string that starts a doc comment (e.g. '/**')
197 > */
198 > open: string;
199 > /**
200 > * The string that appears on the last line and closes the doc comment (e.g. ' * /').
201 > */
202 > close?: string;
203 > }
204 >
205 > /**
206 > * A tuple of two characters, like a pair of
207 > * opening and closing brackets.
208 > */
209 > export type CharacterPair = [string, string];
210 >
211 > export interface IAutoClosingPair {
212 > open: string;
213 > close: string;
214 > }
215 >
216 > export interface IAutoClosingPairConditional extends IAutoClosingPair {
217 > notIn?: string[];
218 > }
219 >
220 > /**
221 > * Describes what to do with the indentation when pressing Enter.
222 > */
223 > export enum IndentAction {
224 > /**
225 > * Insert new line and copy the previous line's indentation.
226 > */
227 > None = 0,
228 > /**
229 > * Insert new line and indent once (relative to the previous line's indentation).
230 > */
231 > Indent = 1,
232 > /**
233 > * Insert two new lines:
234 > * - the first one indented which will hold the cursor
235 > * - the second one at the same indentation level
236 > */
237 > IndentOutdent = 2,
238 > /**
239 > * Insert new line and outdent once (relative to the previous line's indentation).
240 > */
241 > Outdent = 3
242 > }
243 >
244 > /**
245 > * Describes what to do when pressing Enter.
246 > */
247 > export interface EnterAction {
248 > /**
249 > * Describe what to do with the indentation.
250 > */
251 > indentAction: IndentAction;
252 > /**
253 > * Describes text to be appended after the new line and after the indentation.
254 > */
255 > appendText?: string;
256 > /**
257 > * Describes the number of characters to remove from the new line's indentation.
258 > */
259 > removeText?: number;
260 > }
261 >
262 > /**
263 > * @internal
264 > */
265 > export interface CompleteEnterAction {
266 > /**
267 > * Describe what to do with the indentation.
268 > */
269 > indentAction: IndentAction;
270 > /**
271 > * Describes text to be appended after the new line and after the indentation.
272 > */
273 > appendText: string;
274 > /**
275 > * Describes the number of characters to remove from the new line's indentation.
276 > */
277 > removeText: number;
278 > /**
279 > * The line's indentation minus removeText
280 > */
281 > indentation: string;
282 > }
283 >
284 > /**
285 > * @internal
286 > */
287 > export class StandardAutoClosingPairConditional {
288 >
289 > readonly open: string;
290 > readonly close: string;
291 > private readonly _inString: boolean;
292 > private readonly _inComment: boolean;
293 > private readonly _inRegEx: boolean;
294 > private _neutralCharacter: string | null = null;
295 > private _neutralCharacterSearched: boolean = false;
296 >
297 > constructor(source: IAutoClosingPairConditional) {
298 this.open = source.open;
299 this.close = source.close;
321 }
322 }
324 > public isOK(standardToken: StandardTokenType): boolean {
325 switch (standardToken) {
326 case StandardTokenType.Other:
334 }
335 }
337 > public shouldAutoClose(context: ScopedLineTokens, column: number): boolean {
338 // Always complete on empty line
339 if (context.getTokenCount() === 0) {
345 return this.isOK(standardTokenType);
346 }
348 > private _findNeutralCharacterInRange(fromCharCode: number, toCharCode: number): string | null {
349 for (let charCode = fromCharCode; charCode <= toCharCode; charCode++) {
350 const character = String.fromCharCode(charCode);
355 return null;
356 }
358 > /**
359 > * Find a character in the range [0-9a-zA-Z] that does not appear in the open or close
360 > */
361 > public findNeutralCharacter(): string | null {
362 if (!this._neutralCharacterSearched) {
363 this._neutralCharacterSearched = true;
374 return this._neutralCharacter;
375 }
377 >
378 > /**
379 > * @internal
380 > */
381 > export class AutoClosingPairs {
382 > // it is useful to be able to get pairs using either end of open and close
383 >
384 > /** Key is first character of open */
385 > public readonly autoClosingPairsOpenByStart: Map<string, StandardAutoClosingPairConditional[]>;
386 > /** Key is last character of open */
387 > public readonly autoClosingPairsOpenByEnd: Map<string, StandardAutoClosingPairConditional[]>;
388 > /** Key is first character of close */
389 > public readonly autoClosingPairsCloseByStart: Map<string, StandardAutoClosingPairConditional[]>;
390 > /** Key is last character of close */
391 > public readonly autoClosingPairsCloseByEnd: Map<string, StandardAutoClosingPairConditional[]>;
392 > /** Key is close. Only has pairs that are a single character */
393 > public readonly autoClosingPairsCloseSingleChar: Map<string, StandardAutoClosingPairConditional[]>;
394 >
395 > constructor(autoClosingPairs: StandardAutoClosingPairConditional[]) {
396 this.autoClosingPairsOpenByStart = new Map<string, StandardAutoClosingPairConditional[]>();
397 this.autoClosingPairsOpenByEnd = new Map<string, StandardAutoClosingPairConditional[]>();
409 }
410 }
412 >
413 function appendEntry<K, V>(target: Map<K, V[]>, key: K, value: V): void {
414 if (target.has(key)) {