Skip to content

Commit 214e424

Browse files
committed
(PowerShellGH-1336) Add syntax folding for braces and parentheses
This commit adds detection of text regions bounded by braces { } and parentheses ( ). This provides syntax aware folding for functions, arrays and hash tables.
1 parent e06efb8 commit 214e424

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

src/features/Folding.ts

+48
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,38 @@ export class FoldingProvider implements vscode.FoldingRangeProvider {
220220
return foldingRanges;
221221
}
222222

223+
/**
224+
* Given a start and end textmate scope name, find matching grammar tokens
225+
* and pair them together. Uses a simple stack to take into account nested regions.
226+
* @param tokens List of grammar tokens to parse
227+
* @param startScopeName The name of the starting scope to match
228+
* @param endScopeName The name of the ending scope to match
229+
* @param matchType The type of range this matched token pair represents e.g. A comment
230+
* @param document The source text document
231+
* @returns A list of LineNumberRange objects of the matched token scopes
232+
*/
233+
private matchScopeElements(
234+
tokens: ITokenList,
235+
startScopeName: string,
236+
endScopeName: string,
237+
matchType: vscode.FoldingRangeKind,
238+
document: vscode.TextDocument,
239+
): ILineNumberRangeList {
240+
const result = [];
241+
const tokenStack = [];
242+
243+
tokens.forEach((token) => {
244+
if (token.scopes.indexOf(startScopeName) !== -1) {
245+
tokenStack.push(token);
246+
}
247+
if (token.scopes.indexOf(endScopeName) !== -1) {
248+
result.unshift((new LineNumberRange(matchType)).fromTokenPair(tokenStack.pop(), token, document));
249+
}
250+
});
251+
252+
return result;
253+
}
254+
223255
/**
224256
* Given a list of tokens, return a list of line number ranges which could be folding regions in the document
225257
* @param tokens List of grammar tokens to parse
@@ -232,6 +264,22 @@ export class FoldingProvider implements vscode.FoldingRangeProvider {
232264
): ILineNumberRangeList {
233265
const matchedTokens: ILineNumberRangeList = [];
234266

267+
// Find matching braces { -> }
268+
this.matchScopeElements(
269+
tokens,
270+
"punctuation.section.braces.begin.powershell",
271+
"punctuation.section.braces.end.powershell",
272+
vscode.FoldingRangeKind.Region, document)
273+
.forEach((match) => { matchedTokens.push(match); });
274+
275+
// Find matching parentheses ( -> )
276+
this.matchScopeElements(
277+
tokens,
278+
"punctuation.section.group.begin.powershell",
279+
"punctuation.section.group.end.powershell",
280+
vscode.FoldingRangeKind.Region, document)
281+
.forEach((match) => { matchedTokens.push(match); });
282+
235283
return matchedTokens;
236284
}
237285
}

0 commit comments

Comments
 (0)