1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package cmd
6
7import (
8	"context"
9	"flag"
10	"fmt"
11
12	"golang.org/x/tools/internal/lsp/protocol"
13	"golang.org/x/tools/internal/span"
14	"golang.org/x/tools/internal/tool"
15)
16
17// foldingRanges implements the folding_ranges verb for gopls
18type foldingRanges struct {
19	app *Application
20}
21
22func (r *foldingRanges) Name() string      { return "folding_ranges" }
23func (r *foldingRanges) Usage() string     { return "<file>" }
24func (r *foldingRanges) ShortHelp() string { return "display selected file's folding ranges" }
25func (r *foldingRanges) DetailedHelp(f *flag.FlagSet) {
26	fmt.Fprint(f.Output(), `
27Example:
28
29  $ gopls folding_ranges helper/helper.go
30`)
31	f.PrintDefaults()
32}
33
34func (r *foldingRanges) Run(ctx context.Context, args ...string) error {
35	if len(args) != 1 {
36		return tool.CommandLineErrorf("folding_ranges expects 1 argument (file)")
37	}
38
39	conn, err := r.app.connect(ctx)
40	if err != nil {
41		return err
42	}
43	defer conn.terminate(ctx)
44
45	from := span.Parse(args[0])
46	file := conn.AddFile(ctx, from.URI())
47	if file.err != nil {
48		return file.err
49	}
50
51	p := protocol.FoldingRangeParams{
52		TextDocument: protocol.TextDocumentIdentifier{
53			URI: protocol.URIFromSpanURI(from.URI()),
54		},
55	}
56
57	ranges, err := conn.FoldingRange(ctx, &p)
58	if err != nil {
59		return err
60	}
61
62	for _, r := range ranges {
63		fmt.Printf("%v:%v-%v:%v\n",
64			r.StartLine+1,
65			r.StartCharacter+1,
66			r.EndLine+1,
67			r.EndCharacter,
68		)
69	}
70
71	return nil
72}
73