@@ -173,6 +173,22 @@ interface ILineNumberRangeList extends Array<LineNumberRange> { }
173
173
export class FoldingProvider implements vscode . FoldingRangeProvider {
174
174
private powershellGrammar : IGrammar ;
175
175
176
+ /**
177
+ * These regular expressions are used to match lines which mark the start and end of region comment in a PowerShell
178
+ * script. They are based on the defaults in the VS Code Language Configuration at;
179
+ * https://github.com/Microsoft/vscode/blob/64186b0a26/extensions/powershell/language-configuration.json#L26-L31
180
+ */
181
+ private readonly startRegionText = / ^ \s * # r e g i o n \b / i;
182
+ private readonly endRegionText = / ^ \s * # e n d r e g i o n \b / i;
183
+ /**
184
+ * This regular expressions is used to detect a line comment (as opposed to an inline comment), that is not a region
185
+ * block directive i.e.
186
+ * - No text between the beginning of the line and `#`
187
+ * - Comment does start with region
188
+ * - Comment does start with endregion
189
+ */
190
+ private readonly lineCommentText = / \s * # (? ! r e g i o n \b | e n d r e g i o n \b ) / i;
191
+
176
192
constructor (
177
193
powershellGrammar : IGrammar ,
178
194
) {
@@ -310,34 +326,16 @@ export class FoldingProvider implements vscode.FoldingRangeProvider {
310
326
}
311
327
312
328
/**
313
- * Given a zero based offset, find the line text preceeding it in the document
329
+ * Given a zero based offset, find the line in the document
314
330
* @param offset Zero based offset in the document
315
331
* @param document The source text document
316
- * @returns The line text preceeding the offset, not including the preceeding Line Feed
332
+ * @returns The line at the offset
317
333
*/
318
- private preceedingText (
334
+ private lineAtOffset (
319
335
offset : number ,
320
336
document : vscode . TextDocument ,
321
- ) : string {
322
- const endPos = document . positionAt ( offset ) ;
323
- const startPos = endPos . translate ( 0 , - endPos . character ) ;
324
-
325
- return document . getText ( new vscode . Range ( startPos , endPos ) ) ;
326
- }
327
-
328
- /**
329
- * Given a zero based offset, find the line text after it in the document
330
- * @param offset Zero based offset in the document
331
- * @param document The source text document
332
- * @returns The line text after the offset, not including the subsequent Line Feed
333
- */
334
- private subsequentText (
335
- offset : number ,
336
- document : vscode . TextDocument ,
337
- ) : string {
338
- const startPos : vscode . Position = document . positionAt ( offset ) ;
339
- const endPos : vscode . Position = document . lineAt ( document . positionAt ( offset ) ) . range . end ;
340
- return document . getText ( new vscode . Range ( startPos , endPos ) ) ;
337
+ ) : vscode . TextLine {
338
+ return document . lineAt ( document . positionAt ( offset ) ) ;
341
339
}
342
340
343
341
/**
@@ -353,19 +351,16 @@ export class FoldingProvider implements vscode.FoldingRangeProvider {
353
351
document : vscode . TextDocument ,
354
352
) : ILineNumberRangeList {
355
353
const result = [ ] ;
356
-
357
- const emptyLine = / ^ \s * $ / ;
358
-
359
354
let startLine : number = - 1 ;
360
355
let nextLine : number = - 1 ;
361
356
362
357
tokens . forEach ( ( token ) => {
363
358
if ( token . scopes . indexOf ( "punctuation.definition.comment.powershell" ) !== - 1 ) {
359
+ const line : vscode . TextLine = this . lineAtOffset ( token . startIndex , document ) ;
364
360
// The punctuation.definition.comment.powershell token matches new-line comments
365
- // and inline comments e.g. `$x = 'foo' # inline comment`. We are only interested
366
- // in comments which begin the line i.e. no preceeding text
367
- if ( emptyLine . test ( this . preceedingText ( token . startIndex , document ) ) ) {
368
- const lineNum = document . positionAt ( token . startIndex ) . line ;
361
+ // and inline comments e.g. `$x = 'foo' # inline comment`.
362
+ if ( this . lineCommentText . test ( line . text ) ) {
363
+ const lineNum = line . lineNumber ;
369
364
// A simple pattern for keeping track of contiguous numbers in a known sorted array
370
365
if ( startLine === - 1 ) {
371
366
startLine = lineNum ;
@@ -420,21 +415,14 @@ export class FoldingProvider implements vscode.FoldingRangeProvider {
420
415
document : vscode . TextDocument ,
421
416
) : ITokenList {
422
417
const result = [ ] ;
423
-
424
- const emptyLine = / ^ \s * $ / ;
425
- const startRegionText = / ^ # r e g i o n \b / i;
426
- const endRegionText = / ^ # e n d r e g i o n \b / i;
427
-
428
418
tokens . forEach ( ( token ) => {
429
419
if ( token . scopes . indexOf ( "punctuation.definition.comment.powershell" ) !== - 1 ) {
430
- if ( emptyLine . test ( this . preceedingText ( token . startIndex , document ) ) ) {
431
- const commentText = this . subsequentText ( token . startIndex , document ) ;
432
- if ( startRegionText . test ( commentText ) ) {
433
- result . push ( this . addTokenScope ( token , "custom.start.region" ) ) ;
434
- }
435
- if ( endRegionText . test ( commentText ) ) {
436
- result . push ( this . addTokenScope ( token , "custom.end.region" ) ) ;
437
- }
420
+ const line : string = this . lineAtOffset ( token . startIndex , document ) . text ;
421
+ if ( this . startRegionText . test ( line ) ) {
422
+ result . push ( this . addTokenScope ( token , "custom.start.region" ) ) ;
423
+ }
424
+ if ( this . endRegionText . test ( line ) ) {
425
+ result . push ( this . addTokenScope ( token , "custom.end.region" ) ) ;
438
426
}
439
427
}
440
428
} ) ;
0 commit comments