tools/gopls: add cmd support for highlight

This change adds command line support for highlight.
Provided with an identifier position, it will display
the list of highlights for that within the same file.

Example:

$ gopls highlight ~/tmp/foo/main.go:3:9
$
$ 3:9-6:0
$ 10:22-11:32
$ 12:10-12:9
$ 12:20-30:0

Updates golang/go#32875

Change-Id: I5de73d9fbd9bcc59a3f62e7e9a1331bc3866bc75
Reviewed-on: https://go-review.googlesource.com/c/tools/+/207291
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Francesco Renzi 2019-11-18 07:14:06 +00:00 committed by Rebecca Stambler
parent b832835c53
commit 20805546e7
4 changed files with 108 additions and 5 deletions

View File

@ -144,9 +144,10 @@ func (app *Application) commands() []tool.Application {
&check{app: app},
&foldingRanges{app: app},
&format{app: app},
&links{app: app},
&highlight{app: app},
&implementation{app: app},
&imports{app: app},
&links{app: app},
&query{app: app},
&references{app: app},
&rename{app: app},

View File

@ -0,0 +1,81 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cmd
import (
"context"
"flag"
"fmt"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/tool"
)
// highlight implements the highlight verb for gopls
type highlight struct {
app *Application
}
func (r *highlight) Name() string { return "highlight" }
func (r *highlight) Usage() string { return "<position>" }
func (r *highlight) ShortHelp() string { return "display selected identifier's highlights" }
func (r *highlight) DetailedHelp(f *flag.FlagSet) {
fmt.Fprint(f.Output(), `
Example:
$ # 1-indexed location (:line:column or :#offset) of the target identifier
$ gopls highlight helper/helper.go:8:6
$ gopls highlight helper/helper.go:#53
gopls highlight flags are:
`)
f.PrintDefaults()
}
func (r *highlight) Run(ctx context.Context, args ...string) error {
if len(args) != 1 {
return tool.CommandLineErrorf("highlight expects 1 argument (position)")
}
conn, err := r.app.connect(ctx)
if err != nil {
return err
}
defer conn.terminate(ctx)
from := span.Parse(args[0])
file := conn.AddFile(ctx, from.URI())
if file.err != nil {
return file.err
}
loc, err := file.mapper.Location(from)
if err != nil {
return err
}
p := protocol.DocumentHighlightParams{
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
Position: loc.Range.Start,
},
}
highlights, err := conn.DocumentHighlight(ctx, &p)
if err != nil {
return err
}
for _, h := range highlights {
l := protocol.Location{Range: h.Range}
s, err := file.mapper.Span(l)
if err != nil {
return err
}
fmt.Println(s)
}
return nil
}

View File

@ -95,10 +95,6 @@ func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completi
//TODO: add command line completions tests when it works
}
func (r *runner) Highlight(t *testing.T, src span.Span, locations []span.Span) {
//TODO: add command line highlight tests when it works
}
func (r *runner) PrepareRename(t *testing.T, src span.Span, want *source.PrepareItem) {
//TODO: add command line prepare rename tests when it works
}

View File

@ -0,0 +1,25 @@
package cmdtest
import (
"testing"
"fmt"
"golang.org/x/tools/internal/span"
)
func (r *runner) Highlight(t *testing.T, spn span.Span, spans []span.Span) {
var expect string
for _, l := range spans {
expect += fmt.Sprintln(l)
}
expect = r.Normalize(expect)
uri := spn.URI()
filename := uri.Filename()
target := filename + ":" + fmt.Sprint(spn.Start().Line()) + ":" + fmt.Sprint(spn.Start().Column())
got, _ := r.NormalizeGoplsCmd(t, "highlight", target)
if expect != got {
t.Errorf("highlight failed for %s expected:\n%s\ngot:\n%s", target, expect, got)
}
}