nickna / nickna/SharpTS

LSP: add syntax-backed folding ranges in full mode

Open
#1,397 0 comments 0 reactions 0 assignees View on GitHub
deferred enhancement
Dominant language
C#
Stars
154
Forks
4
Avg merge
2h 46m
Merged PRs (30d)
189

Description

Parent epic: #1390. Deferred from #1306. This can proceed in parallel with the semantic/member work and may use existing statement/declaration spans plus delimiter tokens.

## Goal

Provide deterministic `textDocument/foldingRange` results for standalone `full` mode, including TypeScript/TSX constructs that minimal editors cannot always derive themselves.

## Work

- [ ] Register folding ranges in `full` mode only and honor client `lineFoldingOnly` and `rangeLimit` capabilities.
- [ ] Produce ranges for multiline functions/methods/arrows, classes/interfaces/enums/namespaces, blocks/control flow, switch bodies/cases where useful, object/array/type literals, multiline parameter/type-argument lists, JSX elements/fragments, template literals, and multiline comments.
- [ ] Add import-group and region folding only when the source syntax makes the boundary deterministic.
- [ ] Reuse source spans/delimiter tokens rather than reparsing source with ad hoc regular expressions; use #1391 if a claimed range cannot be made exact from existing provenance.
- [ ] Exclude single-line, empty, invalid, duplicate, and crossing ranges; preserve legitimate nesting and deterministic ordering.
- [ ] Define fold kinds (`comment`, `imports`, `region`) and collapsed text only where protocol/client support is reliable.
- [ ] Remain resilient under parser recovery and incomplete edits, using document snapshots and cancellation.
- [ ] Document supported constructs and the intentional absence from `interop-only`.

## Verification

- [ ] Exact line/character tests cover every supported construct, deep nesting, adjacent ranges, same-line braces, Allman braces, CRLF/LF, Unicode, comments, templates, TSX, decorators, and generic/type literals.
- [ ] Structural invariant tests assert start precedes end, no single-line folds, ranges are within the document, duplicates are absent, and ranges are either nested or disjoint rather than crossing.
- [ ] Malformed and half-typed source returns best-effort valid ranges without exceptions.
- [ ] `lineFoldingOnly` and small `rangeLimit` requests return deterministic valid subsets.
- [ ] Stale-version and cancellation tests do not publish obsolete ranges.
- [ ] Real initialize handshakes advertise folding only in `full`; `interop-only` remains unchanged.
- [ ] Add an end-to-end JSON-RPC snapshot for a representative TSX/module file.
- [ ] Benchmark a large generated/nested file and document latency and allocation impact.
- [ ] Full unit, language-server pack, extension compile, Test262, and TypeScript conformance validation is green.

## Success criteria

Supported multiline constructs fold at the intended boundaries in standalone clients, all ranges satisfy LSP structural invariants under valid and recovered syntax, client limits are honored, and coexistence mode is unaffected.

## Non-goals

- Competing with an editor's richer native Tree-sitter folds.
- Heuristic folding whose boundaries are not source-structurally defensible.
- Folding runtime/generated compiler structures.

Contributor guide

Open the contributing guide

Research direction

The issue names no source files or test paths. Start by locating standalone `full`-mode registration, existing statement/declaration spans, and delimiter-token provenance; done means deterministic valid folding ranges, capability limits, recovery behavior, and the listed unit, JSON-RPC, handshake, and benchmark verification pass without changing `interop-only`.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, typescript
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.