mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 11:35:42 -06:00
Add support for custom outlining regions
This commit is contained in:
parent
2b28916e5e
commit
9726ba1198
@ -2037,6 +2037,10 @@ namespace ts {
|
||||
end: -1;
|
||||
}
|
||||
|
||||
export interface RegionRange extends TextRange {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
// represents a top level: { type } expression in a JSDoc comment.
|
||||
export interface JSDocTypeExpression extends TypeNode {
|
||||
kind: SyntaxKind.JSDocTypeExpression;
|
||||
|
||||
@ -6,6 +6,10 @@ namespace ts.OutliningElementsCollector {
|
||||
export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] {
|
||||
const elements: OutliningSpan[] = [];
|
||||
let depth = 0;
|
||||
const regions: RegionRange[] = [];
|
||||
const regionText = "#region";
|
||||
const regionStart = new RegExp("// #region( .+| *)", "g");
|
||||
const regionEnd = new RegExp("// #endregion *");
|
||||
|
||||
walk(sourceFile);
|
||||
return elements;
|
||||
@ -35,6 +39,18 @@ namespace ts.OutliningElementsCollector {
|
||||
}
|
||||
}
|
||||
|
||||
function addOutliningSpanRegions(regionSpan: RegionRange) {
|
||||
if (regionSpan) {
|
||||
const span: OutliningSpan = {
|
||||
textSpan: createTextSpanFromBounds(regionSpan.pos, regionSpan.end),
|
||||
hintSpan: createTextSpanFromBounds(regionSpan.pos, regionSpan.end),
|
||||
bannerText: regionSpan.name,
|
||||
autoCollapse: false,
|
||||
};
|
||||
elements.push(span);
|
||||
}
|
||||
}
|
||||
|
||||
function addOutliningForLeadingCommentsForNode(n: Node) {
|
||||
const comments = ts.getLeadingCommentRangesOfNode(n, sourceFile);
|
||||
|
||||
@ -89,12 +105,65 @@ namespace ts.OutliningElementsCollector {
|
||||
return isFunctionBlock(node) && node.parent.kind !== SyntaxKind.ArrowFunction;
|
||||
}
|
||||
|
||||
function isRegionStart(range: CommentRange) {
|
||||
const comment = sourceFile.text.substring(range.pos, range.end);
|
||||
const result = comment.match(regionStart);
|
||||
|
||||
if (result && result.length > 0) {
|
||||
const name = result[0].substring(10).trim();
|
||||
if (name) {
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
return regionText;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function isRegionEnd(range: CommentRange) {
|
||||
const comment = sourceFile.text.substring(range.pos, range.end);
|
||||
return comment.match(regionEnd);
|
||||
}
|
||||
|
||||
function addRegionsNearNode(n: Node) {
|
||||
const comments = ts.getLeadingCommentRangesOfNode(n, sourceFile);
|
||||
|
||||
if (n.kind !== SyntaxKind.SourceFile && comments) {
|
||||
for (const currentComment of comments) {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
if (currentComment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
const name = isRegionStart(currentComment);
|
||||
if (name) {
|
||||
const region: RegionRange = {
|
||||
pos: currentComment.pos,
|
||||
end: currentComment.end,
|
||||
name,
|
||||
};
|
||||
regions.push(region);
|
||||
}
|
||||
else if (isRegionEnd(currentComment)) {
|
||||
const region = regions.pop();
|
||||
|
||||
if (region) {
|
||||
region.end = currentComment.end;
|
||||
addOutliningSpanRegions(region);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function walk(n: Node): void {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
if (depth > maxDepth) {
|
||||
return;
|
||||
}
|
||||
|
||||
addRegionsNearNode(n);
|
||||
|
||||
if (isDeclaration(n)) {
|
||||
addOutliningForLeadingCommentsForNode(n);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user