Skip to content

Folding ​

The model lists the ranges a view can fold and keeps no fold state; the view tracks which ranges are collapsed.

Folding ranges ​

getFoldingRanges(options?) returns the document's folds as FoldingRanges. Without options it returns multiline bracket pairs and block comments. Pass a language for the rest:

kindWhat foldsNeeds
bracketA {}, [] or () pair over several lines
commentA block comment
indentationLines indented deeper than the one above themindentation: true
importsA run of import linesa language
line-commentsA run of line commentsa language
regionWhat stands between // region and // endregion markersa language
blockA Markdown front matter, code fence or table, a PHP heredoc or <?php ?> blocka language
sectionWhat a Markdown heading holdsa language
serverA range a language server named that the text has no fold forhints

FoldingOptions turn one kind off with false: brackets, comments, imports, regions and lineComments. minLines (default 1) is how many lines past its first a range must span, and tabSize measures indentation. Lines are zero-based and inclusive. from and to are the offsets of the folded stretch.

ts
const document = new DocumentModel('import { a } from "a";\nimport { b } from "b";\n\nconst list = [\n    1,\n    2\n];\n');

document.getFoldingRanges({ language: 'typescript' }).map((range) => [range.kind, range.role, range.startLine, range.endLine]);
// [['imports', 'imports', 0, 1], ['bracket', 'array-literal', 3, 6]]

Roles ​

A range may carry a role, a FoldRole that says what it is. A view uses it to fold certain ranges when a file opens, such as the imports and the file header. The scanner finds:

  • file-header, the first comment of a file, and doc-comment.
  • imports and region.
  • object-literal and array-literal, in TypeScript and JavaScript.
  • attribute (a PHP #[ list), php-tag and heredoc.
  • front-matter, code-fence and table, in Markdown.

function-body, method-body, class-body and tag need to know what a range belongs to, which a lexical scan cannot tell. They come from hints.

Hints from a language server ​

hints is a FoldHints with two lists, in offsets of the text, which a host fills from a language server's symbols and folding ranges:

  • symbols are FoldSymbolHints: the from and to of a symbol and its body, one of function, method, class or value. A symbol hint names the bracket pair or indented block that ends where the symbol ends. A value whose initializer is a function gets a function body.
  • ranges are FoldRangeHints: a from and to, the LSP kind, and optional head and tail offsets from the protocol's startCharacter and endCharacter. A range hint without a matching fold becomes a server range.
ts
const text = 'function total(items) {\n    return items.length;\n}\n';
const document = new DocumentModel(text);

document.getFoldingRanges({
    language: 'typescript',
    hints: { symbols: [{ from: 0, to: 50, body: 'function' }] }
});
// [{ startLine: 0, endLine: 2, kind: 'bracket', role: 'function-body', from: 22, to: 50 }]

A range with head and tail folds within its first and last lines rather than whole lines, so a list of imports can collapse to its first word. Folding in the editor shows how the view uses all of this.

Licenses and third-party notices are listed in each package.