Folding Ranges
Fold Kinds
Block folding
Functions, types, namespaces and lambdas form folding ranges
Nested compound-statement folding
Nested control-flow bodies form folding ranges
Multi-line list folding
Multiline parameter, argument, initializer and capture lists form folding ranges
Access-specifier section folding
Access-specifier regions within a class form folding ranges
Preprocessor conditional folding
Each branch of a conditional forms a folding range up to the directive that ends it, which stays visible
Pragma region folding
Named pragma regions form folding ranges
Pragma classification
Only the first argument token decides region/endregion
Comment folding
Multiline block comments and runs of line comments fold
Line comments on consecutive lines fold as one run below the first line, which stays visible; a blank line or a line of code ends the run. A block comment folds on its delimiters like a brace pair. A comment trailing code does not fold.
Include region folding
Consecutive include directives fold as one run below the first include
A blank line, a comment line or another directive ends the run; includes inside a conditional branch fold within it, whether or not the branch is taken.
Raw string literal folding
Multiline raw string literals fold on their delimiters
The placeholder repeats the encoding prefix, a custom delimiter and a literal suffix. A raw string written in a macro argument folds where it is written.
using declaration blocks
Consecutive using declarations and directives fold below the first one
A blank line or any other line ends the run, and alias declarations do not join one, nor does a declaration sharing its line with other code. Using declarations produced by macros fold at the invocations.
Template parameter list folding
Multiline template parameter lists fold on their angle brackets
Class, function, variable and alias templates, partial specializations, the lists an out-of-line member definition repeats, template template parameters and lambdas with explicit template parameters all fold their parameter lists.
Template specializations and instantiations
Written specializations and their members fold; instantiated declarations reuse the pattern's source locations and do not fold it again
Abbreviated function templates
Bodies of functions with auto or constrained auto parameters fold like any other function
Macro-generated folding
Braces and access specifiers spelled through macros fold at the invocation site
Coroutine bodies
The written block folds exactly once and the coroutine transformation wrapper adds no duplicate fold; a coroutine lambda keeps its body fold
Initializer-list constructions
The constructor's braces and the nested initializer list share delimiters and fold once; a parenthesized list argument keeps both folds
Macro-argument folding
Code written inside macro arguments folds where it is written
Linkage specification blocks
extern "C" blocks form folding ranges, also behind the usual __cplusplus guards
Module fragments and export blocks
The global and private module fragments and export blocks form folding ranges
Refinements
collapsedText placeholder (LSP 3.17)
Folded ranges can show a summary
Client support: VS Code does not support
collapsedTextyet (vscode#70794 — still open); Neovim with nvim-lsp supports it natively. Clients that do not implement this field will silently ignore it — the folding still works, only the placeholder text is missing.
Declaration-line folding
A declaration's body folds from the line holding its name
When the opening brace of a function, class or namespace sits below the name — on a line of its own, or after a signature spanning several lines — a client that folds whole lines starts the fold on the name's line, so the folded declaration keeps showing what it is. A client folding by characters starts at the brace and keeps everything before it visible anyway. A conditional directive between the name and the brace keeps the fold at the brace.
Client support: VS Code still leaves the closing
}on a separate line rather than collapsing it onto the signature line (vscode#3352 — still open).
Inactive preprocessor branches
Untaken branches fold like taken ones
Every branch of a conditional folds whether or not the compile takes it, conditionals nested in an untaken branch included, so dead code can be folded away by hand. Untaken code is dimmed by the inactive modifier of semantic tokens; the folds themselves do not tell the branches apart.
Single-line constructs stay unfolded
A fold that hides nothing is noise
