-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gopls/internal/lsp: add selection range request
selectionRange defines the textDocument/selectionRange feature, which, given a list of positions within a file, reports a linked list of enclosing syntactic blocks, innermost first. See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_selectionRange. This feature can be used by a client to implement "expand selection" in a language-aware fashion. Multiple input positions are supported to allow for multiple cursors, and the entire path up to the whole document is returned for each cursor to avoid multiple round-trips when the user is likely to issue this command multiple times in quick succession. Fixes golang/go#36679 Change-Id: I4852db4b40be24b3dc13e4d9d9238c1a9ac5f824 GitHub-Last-Rev: 0a11741 GitHub-Pull-Request: #416 Reviewed-on: https://go-review.googlesource.com/c/tools/+/452315 Reviewed-by: Alan Donovan <adonovan@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com>
- Loading branch information
1 parent
18f76ec
commit d72a64a
Showing
10 changed files
with
204 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright 2022 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 lsp | ||
|
||
import ( | ||
"context" | ||
|
||
"golang.org/x/tools/go/ast/astutil" | ||
"golang.org/x/tools/gopls/internal/lsp/protocol" | ||
"golang.org/x/tools/gopls/internal/lsp/source" | ||
"golang.org/x/tools/internal/event" | ||
) | ||
|
||
// selectionRange defines the textDocument/selectionRange feature, | ||
// which, given a list of positions within a file, | ||
// reports a linked list of enclosing syntactic blocks, innermost first. | ||
// | ||
// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_selectionRange. | ||
// | ||
// This feature can be used by a client to implement "expand selection" in a | ||
// language-aware fashion. Multiple input positions are supported to allow | ||
// for multiple cursors, and the entire path up to the whole document is | ||
// returned for each cursor to avoid multiple round-trips when the user is | ||
// likely to issue this command multiple times in quick succession. | ||
func (s *Server) selectionRange(ctx context.Context, params *protocol.SelectionRangeParams) ([]protocol.SelectionRange, error) { | ||
ctx, done := event.Start(ctx, "lsp.Server.documentSymbol") | ||
defer done() | ||
|
||
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) | ||
defer release() | ||
if !ok { | ||
return nil, err | ||
} | ||
|
||
pgf, err := snapshot.ParseGo(ctx, fh, source.ParseFull) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
result := make([]protocol.SelectionRange, len(params.Positions)) | ||
for i, protocolPos := range params.Positions { | ||
pos, err := pgf.Mapper.Pos(protocolPos) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
path, _ := astutil.PathEnclosingInterval(pgf.File, pos, pos) | ||
|
||
tail := &result[i] // tail of the Parent linked list, built head first | ||
|
||
for j, node := range path { | ||
rng, err := pgf.Mapper.PosRange(node.Pos(), node.End()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Add node to tail. | ||
if j > 0 { | ||
tail.Parent = &protocol.SelectionRange{} | ||
tail = tail.Parent | ||
} | ||
tail.Range = rng | ||
} | ||
} | ||
|
||
return result, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package foo | ||
|
||
import "time" | ||
|
||
func Bar(x, y int, t time.Time) int { | ||
zs := []int{1, 2, 3} //@selectionrange("1") | ||
|
||
for _, z := range zs { | ||
x = x + z + y + zs[1] //@selectionrange("1") | ||
} | ||
|
||
return x + y //@selectionrange("+") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
-- selectionrange_foo_12_11 -- | ||
Ranges 0: | ||
11:8-11:13 "x + y" | ||
11:1-11:13 "return x + y" | ||
4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" | ||
4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" | ||
0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" | ||
|
||
-- selectionrange_foo_6_14 -- | ||
Ranges 0: | ||
5:13-5:14 "1" | ||
5:7-5:21 "[]int{1, 2, 3}" | ||
5:1-5:21 "zs := []int{1, 2, 3}" | ||
4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" | ||
4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" | ||
0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" | ||
|
||
-- selectionrange_foo_9_22 -- | ||
Ranges 0: | ||
8:21-8:22 "1" | ||
8:18-8:23 "zs[1]" | ||
8:6-8:23 "x + z + y + zs[1]" | ||
8:2-8:23 "x = x + z + y + zs[1]" | ||
7:22-9:2 "{\\n\t\tx = x + z +...onrange(\"1\")\\n\t}" | ||
7:1-9:2 "for _, z := ran...onrange(\"1\")\\n\t}" | ||
4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" | ||
4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" | ||
0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters