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;