Skip to content

Commit 129e25f

Browse files
committed
Review comments
1 parent b56a19e commit 129e25f

4 files changed

Lines changed: 56 additions & 40 deletions

File tree

server/folding_range_provider.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ type FoldingRangeFilter interface {
3232
IncludeLastFoldingLineForComment() bool
3333
}
3434

35+
// DefaultFoldingRangeFilter provides the standard folding behavior:
36+
// Processes all nodes, excludes last line for nodes ending with closing brackets, and includes last line for comments.
3537
type DefaultFoldingRangeFilter struct{}
3638

3739
func (f *DefaultFoldingRangeFilter) ShouldProcess(node core.AstNode) bool {
@@ -127,20 +129,24 @@ func (p *DefaultFoldingRangeProvider) toFoldingRange(segment *core.TextSegment,
127129
return nil
128130
}
129131

130-
foldRange := segment.Range
131-
if !includeLastLine {
132-
foldRange = core.TextRange{
133-
Start: segment.Range.Start,
134-
End: core.TextLocation{Line: segment.Range.End.Line - 1, Column: segment.Range.End.Column},
135-
}
136-
}
132+
lspRange := segment.Range.LspRange()
133+
endLine := lspRange.End.Line
134+
endChar := lspRange.End.Character
137135

138-
lspRange := foldRange.LspRange()
139-
return &lsp.FoldingRange{
136+
folding := &lsp.FoldingRange{
140137
StartLine: &lspRange.Start.Line,
141-
EndLine: &lspRange.End.Line,
142138
StartCharacter: &lspRange.Start.Character,
143-
EndCharacter: &lspRange.End.Character,
139+
EndLine: &endLine,
144140
Kind: kind,
145141
}
142+
143+
if !includeLastLine {
144+
endLine--
145+
} else {
146+
// Only set EndCharacter when including the last line.
147+
// When not set, LSP defaults to end of line.
148+
folding.EndCharacter = &endChar
149+
}
150+
151+
return folding
146152
}

server/folding_range_provider_test.go

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,13 @@ import (
88
"context"
99
"testing"
1010

11-
"github.com/stretchr/testify/assert"
1211
"github.com/stretchr/testify/require"
13-
core "typefox.dev/fastbelt"
1412
"typefox.dev/fastbelt/internal/grammar"
1513
"typefox.dev/fastbelt/test"
1614
"typefox.dev/fastbelt/util/service"
1715
"typefox.dev/lsp"
1816
)
1917

20-
func assertHasFoldingRange(t *testing.T, result []lsp.FoldingRange, markerRange core.TextRange, label string) {
21-
t.Helper()
22-
for _, fr := range result {
23-
if fr.StartLine == nil || fr.EndLine == nil {
24-
continue
25-
}
26-
27-
if *fr.StartLine == uint32(markerRange.Start.Line) && *fr.EndLine == uint32(markerRange.End.Line) {
28-
if label == "comment" {
29-
assert.Equal(t, "comment", fr.Kind, "Comment folding should have kind='comment'")
30-
}
31-
return
32-
}
33-
}
34-
t.Errorf("Should have folding range for marker '%s' (lines %d-%d)", label, markerRange.Start.Line, markerRange.End.Line)
35-
}
36-
3718
func TestFoldingRangeIntegration(t *testing.T) {
3819
sc := service.NewContainer()
3920
grammar.SetupServices(sc)
@@ -79,13 +60,5 @@ func TestFoldingRangeIntegration(t *testing.T) {
7960
require.NoError(t, err)
8061
require.NotNil(t, result)
8162

82-
// We expect folding ranges for the marked regions plus the grammar root
83-
expectedLabels := []string{"first", "second", "comment", "third"}
84-
assert.Equal(t, len(result), len(expectedLabels)+1, "Should have at least %d folding ranges", len(expectedLabels))
85-
86-
for _, label := range expectedLabels {
87-
markerRange, ok := doc.MarkerRange(label)
88-
require.True(t, ok, "Marker '%s' should exist", label)
89-
assertHasFoldingRange(t, result, markerRange, label)
90-
}
63+
doc.AssertFoldingRanges(result, "first", "second", "comment", "third")
9164
}

test/doc_fixture.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"testing"
88

99
core "typefox.dev/fastbelt"
10+
"typefox.dev/lsp"
1011
)
1112

1213
// Doc wraps a built [core.Document] with assertion methods and marker positions.
@@ -17,6 +18,7 @@ type Doc struct {
1718
Indices []IndexMarker
1819
ctx context.Context
1920
t testing.TB
21+
fixture *Fixture
2022
}
2123

2224
// Ctx returns the context for this document. Pass it to [core.Reference.Ref].
@@ -424,3 +426,38 @@ func MustFindReference[T core.AstNode](d *Doc, label string) *core.Reference[T]
424426
}
425427
return r
426428
}
429+
430+
// AssertFoldingRanges verifies that the given folding ranges contain entries for all specified marker labels.
431+
// Returns the Doc for chaining.
432+
func (d *Doc) AssertFoldingRanges(result []lsp.FoldingRange, labels ...string) *Doc {
433+
d.fixture.t.Helper()
434+
435+
for _, label := range labels {
436+
expectedRange, ok := d.MarkerRange(label)
437+
if !ok {
438+
d.fixture.t.Fatalf("fbtest: no marker with label %q", label)
439+
}
440+
441+
found := false
442+
for _, fr := range result {
443+
if fr.StartLine != nil && fr.EndLine != nil {
444+
if *fr.StartLine == uint32(expectedRange.Start.Line) &&
445+
*fr.EndLine == uint32(expectedRange.End.Line) {
446+
// For comment ranges, also verify the kind
447+
if label == "comment" && fr.Kind != "comment" {
448+
continue
449+
}
450+
found = true
451+
break
452+
}
453+
}
454+
}
455+
456+
if !found {
457+
d.fixture.t.Errorf("fbtest: expected folding range at label %q (lines %d-%d) not found",
458+
label, expectedRange.Start.Line, expectedRange.End.Line)
459+
}
460+
}
461+
462+
return d
463+
}

test/fixture.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func (f *Fixture) ParseAll(uriContentPairs ...string) []*Doc {
158158
}
159159

160160
func (f *Fixture) newDoc(doc *core.Document, ranges []RangeMarker, indices []IndexMarker) *Doc {
161-
return &Doc{Document: doc, Ranges: ranges, Indices: indices, ctx: f.ctx, t: f.t}
161+
return &Doc{Document: doc, Ranges: ranges, Indices: indices, ctx: f.ctx, t: f.t, fixture: f}
162162
}
163163

164164
// extractMarkers scans content for embedded position markers, removes them, and

0 commit comments

Comments
 (0)