Skip to content

Commit 3e53a25

Browse files
committed
gopls/internal/folding_range: display closing parentheses
After this CL, closing braces (or parentheses or brackets) at the end of a folding range will be displayed, so that users can easily add things at the end of the range. Closing string quotes have never been displayed. Fixes: golang/go#75229 Change-Id: I73f45d6b157f6da8e988b0fc6ec63186d4fea408 Reviewed-on: https://go-review.googlesource.com/c/tools/+/704695 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Madeline Kalil <[email protected]>
1 parent 78463a9 commit 3e53a25

File tree

2 files changed

+62
-61
lines changed

2 files changed

+62
-61
lines changed

gopls/internal/golang/folding_range.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,13 @@ func FoldingRange(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle,
5656
(*ast.GenDecl)(nil),
5757
}
5858
for cur := range pgf.Cursor.Preorder(filter...) {
59-
// TODO(suzmue): include trailing empty lines before the closing
60-
// parenthesis/brace.
6159
var kind protocol.FoldingRangeKind
6260
// start and end define the range of content to fold away.
6361
var start, end token.Pos
6462
switch n := cur.Node().(type) {
6563
case *ast.BlockStmt:
6664
// Fold between positions of or lines between "{" and "}".
67-
start, end = bracketedFoldingRange(n.Lbrace, n.Rbrace)
65+
start, end = bracketedFoldingRange(pgf, n.Lbrace, n.Rbrace, lineFoldingOnly)
6866

6967
case *ast.CaseClause:
7068
// Fold from position of ":" to end.
@@ -76,19 +74,19 @@ func FoldingRange(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle,
7674

7775
case *ast.CallExpr:
7876
// Fold between positions of or lines between "(" and ")".
79-
start, end = bracketedFoldingRange(n.Lparen, n.Rparen)
77+
start, end = bracketedFoldingRange(pgf, n.Lparen, n.Rparen, lineFoldingOnly)
8078

8179
case *ast.FieldList:
8280
// Fold between positions of or lines between opening parenthesis/brace and closing parenthesis/brace.
83-
start, end = bracketedFoldingRange(n.Opening, n.Closing)
81+
start, end = bracketedFoldingRange(pgf, n.Opening, n.Closing, lineFoldingOnly)
8482

8583
case *ast.GenDecl:
8684
// If this is an import declaration, set the kind to be protocol.Imports.
8785
if n.Tok == token.IMPORT {
8886
kind = protocol.Imports
8987
}
9088
// Fold between positions of or lines between "(" and ")".
91-
start, end = bracketedFoldingRange(n.Lparen, n.Rparen)
89+
start, end = bracketedFoldingRange(pgf, n.Lparen, n.Rparen, lineFoldingOnly)
9290

9391
case *ast.BasicLit:
9492
// Fold raw string literals from position of "`" to position of "`".
@@ -98,7 +96,7 @@ func FoldingRange(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle,
9896

9997
case *ast.CompositeLit:
10098
// Fold between positions of or lines between "{" and "}".
101-
start, end = bracketedFoldingRange(n.Lbrace, n.Rbrace)
99+
start, end = bracketedFoldingRange(pgf, n.Lbrace, n.Rbrace, lineFoldingOnly)
102100

103101
default:
104102
panic(n)
@@ -137,7 +135,7 @@ func FoldingRange(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle,
137135

138136
// bracketedFoldingRange returns the folding range for nodes with parentheses/braces/brackets
139137
// that potentially can take up multiple lines.
140-
func bracketedFoldingRange(open, close token.Pos) (token.Pos, token.Pos) {
138+
func bracketedFoldingRange(pgf *parsego.File, open, close token.Pos, lineFoldingOnly bool) (token.Pos, token.Pos) {
141139
if !open.IsValid() || !close.IsValid() {
142140
return token.NoPos, token.NoPos
143141
}
@@ -146,8 +144,12 @@ func bracketedFoldingRange(open, close token.Pos) (token.Pos, token.Pos) {
146144
return token.NoPos, token.NoPos
147145
}
148146

147+
if !lineFoldingOnly {
148+
return open + 1, close
149+
}
150+
149151
// Clients with "LineFoldingOnly" set to true can fold only full lines.
150-
// This is checked in the caller.
152+
// This is also checked in the caller.
151153
//
152154
// Clients that support folding ranges can display them in various ways
153155
// (e.g., how are folding ranges marked? is the final line displayed?).
@@ -169,15 +171,14 @@ func bracketedFoldingRange(open, close token.Pos) (token.Pos, token.Pos) {
169171
// var x = []string{"a", ...
170172
// "c" }
171173
//
172-
// This is a change in behavior. The old code would not fold this example,
173-
// nor would it have folded
174-
//
175-
// func foo() { // a non-godoc comment
176-
// ...
177-
// }
178-
// which seems wrong.
174+
// This code displays the final line containing ),},], but not the closing quote
175+
// of a multi-line string
179176

180-
return open + 1, close
177+
prevLineEnd := pgf.Tok.LineStart(safetoken.Line(pgf.Tok, close)) - 1 // there was a previous line
178+
if prevLineEnd <= open { // all the same line
179+
return token.NoPos, token.NoPos
180+
}
181+
return open + 1, prevLineEnd
181182
}
182183

183184
// commentsFoldingRange returns the folding ranges for all comment blocks in file.

gopls/internal/test/marker/testdata/foldingrange/a_lineonly.txt

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ import (<0 kind="imports">
145145
"fmt"
146146
_ "log"
147147
"sort"
148-
"time"
149-
</0>)
148+
"time"</0>
149+
)
150150

151151
import _ "os"
152152

@@ -157,15 +157,15 @@ func Bar() string {<2 kind="">
157157
switch {<3 kind="">
158158
case true:<4 kind="">
159159
if true {<5 kind="">
160-
fmt.Println("true")
161-
</5>} else {<6 kind="">
162-
fmt.Println("false")
163-
</6>}</4>
160+
fmt.Println("true")</5>
161+
} else {<6 kind="">
162+
fmt.Println("false")</6>
163+
}</4>
164164
case false:<7 kind="">
165165
fmt.Println("false")</7>
166166
default:<8 kind="">
167-
fmt.Println("default")</8>
168-
</3>}
167+
fmt.Println("default")</3></8>
168+
}
169169
/* This is a multiline<9 kind="comment">
170170
block
171171
comment */</9>
@@ -177,93 +177,93 @@ func Bar() string {<2 kind="">
177177
_ = []int{<11 kind="">
178178
1,
179179
2,
180-
3,
181-
</11>}
180+
3,</11>
181+
}
182182
_ = [2]string{<12 kind="">"d",
183-
"e",
184-
</12>}
183+
"e",</12>
184+
}
185185
_ = map[string]int{<13 kind="">
186186
"a": 1,
187187
"b": 2,
188-
"c": 3,
189-
</13>}
188+
"c": 3,</13>
189+
}
190190
type T struct {<14 kind="">
191191
f string
192192
g int
193-
h string
194-
</14>}
193+
h string</14>
194+
}
195195
_ = T{<15 kind="">
196196
f: "j",
197197
g: 4,
198-
h: "i",
199-
</15>}
198+
h: "i",</15>
199+
}
200200
x, y := make(chan bool), make(chan bool)
201201
select {<16 kind="">
202202
case val := <-x:<17 kind="">
203203
if val {<18 kind="">
204-
fmt.Println("true from x")
205-
</18>} else {<19 kind="">
206-
fmt.Println("false from x")
207-
</19>}</17>
204+
fmt.Println("true from x")</18>
205+
} else {<19 kind="">
206+
fmt.Println("false from x")</19>
207+
}</17>
208208
case <-y:<20 kind="">
209209
fmt.Println("y")</20>
210210
default:<21 kind="">
211-
fmt.Println("default")</21>
212-
</16>}
211+
fmt.Println("default")</16></21>
212+
}
213213
// This is a multiline comment<22 kind="comment">
214214
// that is not a doc comment.</22>
215215
return <23 kind="">`
216216
this string
217-
is not indented`</23>
218-
</2>}
217+
is not indented`</2></23>
218+
}
219219

220220
func _() {<24 kind="">
221221
slice := []int{1, 2, 3}
222222
sort.Slice(<25 kind="">slice, func(i, j int) bool {<26 kind="">
223223
a, b := slice[i], slice[j]
224-
return a > b
225-
</26>}</25>)
224+
return a > b</25></26>
225+
})
226226

227227
sort.Slice(slice, func(i, j int) bool { return slice[i] > slice[j] })
228228

229229
sort.Slice(<27 kind="">
230230
slice,
231231
func(i, j int) bool {<28 kind="">
232-
return slice[i] > slice[j]
233-
</28>},
234-
</27>)
232+
return slice[i] > slice[j]</28>
233+
},</27>
234+
)
235235

236236
fmt.Println(<29 kind="">
237237
1, 2, 3,
238-
4,
239-
</29>)
238+
4,</29>
239+
)
240240

241241
fmt.Println(<30 kind="">1, 2, 3,
242242
4, 5, 6,
243-
7, 8, 9,
244-
10</30>)
243+
7, 8, 9,</30>
244+
10)
245245

246246
// Call with ellipsis.
247247
_ = fmt.Errorf(<31 kind="">
248248
"test %d %d",
249-
[]any{1, 2, 3}...,
250-
</31>)
249+
[]any{1, 2, 3}...,</31>
250+
)
251251

252252
// Check multiline string.
253253
fmt.Println(<32 kind="">
254254
<33 kind="">`multi
255255
line
256256
string
257257
`</33>,
258-
1, 2, 3,
259-
</32>)
258+
1, 2, 3,</32>
259+
)
260260

261261
// Call without arguments.
262-
_ = time.Now()
263-
</24>}
262+
_ = time.Now()</24>
263+
}
264264

265265
func _(<34 kind="">
266266
a int, b int,
267-
c int,
268-
</34>) {<35 kind="">
269-
</35>}
267+
c int,</34>
268+
) {
269+
}

0 commit comments

Comments
 (0)