mirror of
https://github.com/golang/go
synced 2024-11-18 09:04:49 -07:00
internal/lsp: add config option for SymbolMatch
In preparation for later changes to the workspace Symbol method, we add a separate configuration option keyed by "symbolMatcher" that specifies the type of matcher to use for workspace symbol requests. We also define a new type SymbolMatcher, the type of this new option. We require SymbolMatcher to be a separate type from Matcher because a later CL adds a type of symbol matcher that does not make sense in the context of other uses of Matcher, e.g. completion. Change-Id: Icde7d270b9efb64444f35675a8d0b48ad3b8b3dd Reviewed-on: https://go-review.googlesource.com/c/tools/+/228122 Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
8b0f8a7919
commit
ca5866bcf9
@ -139,3 +139,23 @@ Default: `true`.
|
|||||||
### **staticcheck** *boolean*
|
### **staticcheck** *boolean*
|
||||||
|
|
||||||
If true, it enables the use of the staticcheck.io analyzers.
|
If true, it enables the use of the staticcheck.io analyzers.
|
||||||
|
|
||||||
|
### **matcher** *string*
|
||||||
|
|
||||||
|
Defines the algorithm that is used when calculating completion candidates. Must be one of:
|
||||||
|
|
||||||
|
* `"fuzzy"`
|
||||||
|
* `"caseSensitive"`
|
||||||
|
* `"caseInsensitive"`
|
||||||
|
|
||||||
|
Default: `"caseInsensitive"`.
|
||||||
|
|
||||||
|
### **symbolMatcher** *string*
|
||||||
|
|
||||||
|
Defines the algorithm that is used when calculating workspace symbol results. Must be one of:
|
||||||
|
|
||||||
|
* `"fuzzy"`
|
||||||
|
* `"caseSensitive"`
|
||||||
|
* `"caseInsensitive"`
|
||||||
|
|
||||||
|
Default: `"caseInsensitive"`.
|
||||||
|
@ -241,10 +241,10 @@ func (app *Application) connectRemote(ctx context.Context, remote string) (*conn
|
|||||||
return connection, connection.initialize(ctx, app.options)
|
return connection, connection.initialize(ctx, app.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
var matcherString = map[source.Matcher]string{
|
var matcherString = map[source.SymbolMatcher]string{
|
||||||
source.Fuzzy: "fuzzy",
|
source.SymbolFuzzy: "fuzzy",
|
||||||
source.CaseSensitive: "caseSensitive",
|
source.SymbolCaseSensitive: "caseSensitive",
|
||||||
source.CaseInsensitive: "default",
|
source.SymbolCaseInsensitive: "default",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *connection) initialize(ctx context.Context, options func(*source.Options)) error {
|
func (c *connection) initialize(ctx context.Context, options func(*source.Options)) error {
|
||||||
@ -262,7 +262,7 @@ func (c *connection) initialize(ctx context.Context, options func(*source.Option
|
|||||||
}
|
}
|
||||||
params.Capabilities.TextDocument.DocumentSymbol.HierarchicalDocumentSymbolSupport = opts.HierarchicalDocumentSymbolSupport
|
params.Capabilities.TextDocument.DocumentSymbol.HierarchicalDocumentSymbolSupport = opts.HierarchicalDocumentSymbolSupport
|
||||||
params.InitializationOptions = map[string]interface{}{
|
params.InitializationOptions = map[string]interface{}{
|
||||||
"matcher": matcherString[opts.Matcher],
|
"symbolMatcher": matcherString[opts.SymbolMatcher],
|
||||||
}
|
}
|
||||||
if _, err := c.Server.Initialize(ctx, params); err != nil {
|
if _, err := c.Server.Initialize(ctx, params); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -47,11 +47,11 @@ func (r *workspaceSymbol) Run(ctx context.Context, args ...string) error {
|
|||||||
}
|
}
|
||||||
switch r.Matcher {
|
switch r.Matcher {
|
||||||
case "fuzzy":
|
case "fuzzy":
|
||||||
o.Matcher = source.Fuzzy
|
o.SymbolMatcher = source.SymbolFuzzy
|
||||||
case "caseSensitive":
|
case "caseSensitive":
|
||||||
o.Matcher = source.CaseSensitive
|
o.SymbolMatcher = source.SymbolCaseSensitive
|
||||||
default:
|
default:
|
||||||
o.Matcher = source.CaseInsensitive
|
o.SymbolMatcher = source.SymbolCaseInsensitive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,10 @@ type EditorConfig struct {
|
|||||||
// codeLens command. CodeLens which are not present in this map are left in
|
// codeLens command. CodeLens which are not present in this map are left in
|
||||||
// their default state.
|
// their default state.
|
||||||
CodeLens map[string]bool
|
CodeLens map[string]bool
|
||||||
|
|
||||||
|
// SymbolMatcher is the config associated with the "symbolMatcher" gopls
|
||||||
|
// config option.
|
||||||
|
SymbolMatcher *string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEditor Creates a new Editor.
|
// NewEditor Creates a new Editor.
|
||||||
@ -135,6 +139,10 @@ func (e *Editor) configuration() map[string]interface{} {
|
|||||||
config["codelens"] = e.Config.CodeLens
|
config["codelens"] = e.Config.CodeLens
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if e.Config.SymbolMatcher != nil {
|
||||||
|
config["symbolMatcher"] = *e.Config.SymbolMatcher
|
||||||
|
}
|
||||||
|
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,23 +820,23 @@ func (r *runner) Symbols(t *testing.T, uri span.URI, expectedSymbols []protocol.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) WorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
func (r *runner) WorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
||||||
r.callWorkspaceSymbols(t, query, source.CaseInsensitive, dirs, expectedSymbols)
|
r.callWorkspaceSymbols(t, query, source.SymbolCaseInsensitive, dirs, expectedSymbols)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) FuzzyWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
func (r *runner) FuzzyWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
||||||
r.callWorkspaceSymbols(t, query, source.Fuzzy, dirs, expectedSymbols)
|
r.callWorkspaceSymbols(t, query, source.SymbolFuzzy, dirs, expectedSymbols)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) CaseSensitiveWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
func (r *runner) CaseSensitiveWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
||||||
r.callWorkspaceSymbols(t, query, source.CaseSensitive, dirs, expectedSymbols)
|
r.callWorkspaceSymbols(t, query, source.SymbolCaseSensitive, dirs, expectedSymbols)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) callWorkspaceSymbols(t *testing.T, query string, matcher source.Matcher, dirs map[string]struct{}, expectedSymbols []protocol.SymbolInformation) {
|
func (r *runner) callWorkspaceSymbols(t *testing.T, query string, matcher source.SymbolMatcher, dirs map[string]struct{}, expectedSymbols []protocol.SymbolInformation) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
original := r.server.session.Options()
|
original := r.server.session.Options()
|
||||||
modified := original
|
modified := original
|
||||||
modified.Matcher = matcher
|
modified.SymbolMatcher = matcher
|
||||||
r.server.session.SetOptions(modified)
|
r.server.session.SetOptions(modified)
|
||||||
defer r.server.session.SetOptions(original)
|
defer r.server.session.SetOptions(original)
|
||||||
|
|
||||||
|
@ -98,6 +98,7 @@ func DefaultOptions() Options {
|
|||||||
HoverKind: FullDocumentation,
|
HoverKind: FullDocumentation,
|
||||||
LinkTarget: "pkg.go.dev",
|
LinkTarget: "pkg.go.dev",
|
||||||
Matcher: Fuzzy,
|
Matcher: Fuzzy,
|
||||||
|
SymbolMatcher: SymbolFuzzy,
|
||||||
DeepCompletion: true,
|
DeepCompletion: true,
|
||||||
UnimportedCompletion: true,
|
UnimportedCompletion: true,
|
||||||
CompletionDocumentation: true,
|
CompletionDocumentation: true,
|
||||||
@ -193,6 +194,9 @@ type UserOptions struct {
|
|||||||
// Matcher specifies the type of matcher to use for completion requests.
|
// Matcher specifies the type of matcher to use for completion requests.
|
||||||
Matcher Matcher
|
Matcher Matcher
|
||||||
|
|
||||||
|
// SymbolMatcher specifies the type of matcher to use for symbol requests.
|
||||||
|
SymbolMatcher SymbolMatcher
|
||||||
|
|
||||||
// DeepCompletion allows completion to perform nested searches through
|
// DeepCompletion allows completion to perform nested searches through
|
||||||
// possible candidates.
|
// possible candidates.
|
||||||
DeepCompletion bool
|
DeepCompletion bool
|
||||||
@ -267,6 +271,14 @@ const (
|
|||||||
CaseSensitive
|
CaseSensitive
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type SymbolMatcher int
|
||||||
|
|
||||||
|
const (
|
||||||
|
SymbolFuzzy = SymbolMatcher(iota)
|
||||||
|
SymbolCaseInsensitive
|
||||||
|
SymbolCaseSensitive
|
||||||
|
)
|
||||||
|
|
||||||
type HoverKind int
|
type HoverKind int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -399,6 +411,20 @@ func (o *Options) set(name string, value interface{}) OptionResult {
|
|||||||
o.Matcher = CaseInsensitive
|
o.Matcher = CaseInsensitive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "symbolMatcher":
|
||||||
|
matcher, ok := result.asString()
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
switch matcher {
|
||||||
|
case "fuzzy":
|
||||||
|
o.SymbolMatcher = SymbolFuzzy
|
||||||
|
case "caseSensitive":
|
||||||
|
o.SymbolMatcher = SymbolCaseSensitive
|
||||||
|
default:
|
||||||
|
o.SymbolMatcher = SymbolCaseInsensitive
|
||||||
|
}
|
||||||
|
|
||||||
case "hoverKind":
|
case "hoverKind":
|
||||||
hoverKind, ok := result.asString()
|
hoverKind, ok := result.asString()
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -805,18 +805,18 @@ func (r *runner) Symbols(t *testing.T, uri span.URI, expectedSymbols []protocol.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) WorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
func (r *runner) WorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
||||||
r.callWorkspaceSymbols(t, query, source.CaseInsensitive, dirs, expectedSymbols)
|
r.callWorkspaceSymbols(t, query, source.SymbolCaseInsensitive, dirs, expectedSymbols)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) FuzzyWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
func (r *runner) FuzzyWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
||||||
r.callWorkspaceSymbols(t, query, source.Fuzzy, dirs, expectedSymbols)
|
r.callWorkspaceSymbols(t, query, source.SymbolFuzzy, dirs, expectedSymbols)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) CaseSensitiveWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
func (r *runner) CaseSensitiveWorkspaceSymbols(t *testing.T, query string, expectedSymbols []protocol.SymbolInformation, dirs map[string]struct{}) {
|
||||||
r.callWorkspaceSymbols(t, query, source.CaseSensitive, dirs, expectedSymbols)
|
r.callWorkspaceSymbols(t, query, source.SymbolCaseSensitive, dirs, expectedSymbols)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) callWorkspaceSymbols(t *testing.T, query string, matcher source.Matcher, dirs map[string]struct{}, expectedSymbols []protocol.SymbolInformation) {
|
func (r *runner) callWorkspaceSymbols(t *testing.T, query string, matcher source.SymbolMatcher, dirs map[string]struct{}, expectedSymbols []protocol.SymbolInformation) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
got, err := source.WorkspaceSymbols(r.ctx, matcher, []source.View{r.view}, query)
|
got, err := source.WorkspaceSymbols(r.ctx, matcher, []source.View{r.view}, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
const maxSymbols = 100
|
const maxSymbols = 100
|
||||||
|
|
||||||
// WorkspaceSymbols matches symbols across views using the given query,
|
// WorkspaceSymbols matches symbols across views using the given query,
|
||||||
// according to the matcher Matcher.
|
// according to the SymbolMatcher matcher.
|
||||||
//
|
//
|
||||||
// The workspace symbol method is defined in the spec as follows:
|
// The workspace symbol method is defined in the spec as follows:
|
||||||
//
|
//
|
||||||
@ -32,10 +32,10 @@ const maxSymbols = 100
|
|||||||
// WorkspaceSymbols receives the views []View.
|
// WorkspaceSymbols receives the views []View.
|
||||||
//
|
//
|
||||||
// However, it then becomes unclear what it would mean to call WorkspaceSymbols
|
// However, it then becomes unclear what it would mean to call WorkspaceSymbols
|
||||||
// with a different configured Matcher per View. Therefore we assume that
|
// with a different configured SymbolMatcher per View. Therefore we assume that
|
||||||
// Session level configuration will define the Matcher to be used for the
|
// Session level configuration will define the SymbolMatcher to be used for the
|
||||||
// WorkspaceSymbols method.
|
// WorkspaceSymbols method.
|
||||||
func WorkspaceSymbols(ctx context.Context, matcherType Matcher, views []View, query string) ([]protocol.SymbolInformation, error) {
|
func WorkspaceSymbols(ctx context.Context, matcherType SymbolMatcher, views []View, query string) ([]protocol.SymbolInformation, error) {
|
||||||
ctx, done := event.Start(ctx, "source.WorkspaceSymbols")
|
ctx, done := event.Start(ctx, "source.WorkspaceSymbols")
|
||||||
defer done()
|
defer done()
|
||||||
if query == "" {
|
if query == "" {
|
||||||
@ -102,14 +102,14 @@ type symbolInformation struct {
|
|||||||
|
|
||||||
type matcherFunc func(string) bool
|
type matcherFunc func(string) bool
|
||||||
|
|
||||||
func makeMatcher(m Matcher, query string) matcherFunc {
|
func makeMatcher(m SymbolMatcher, query string) matcherFunc {
|
||||||
switch m {
|
switch m {
|
||||||
case Fuzzy:
|
case SymbolFuzzy:
|
||||||
fm := fuzzy.NewMatcher(query)
|
fm := fuzzy.NewMatcher(query)
|
||||||
return func(s string) bool {
|
return func(s string) bool {
|
||||||
return fm.Score(s) > 0
|
return fm.Score(s) > 0
|
||||||
}
|
}
|
||||||
case CaseSensitive:
|
case SymbolCaseSensitive:
|
||||||
return func(s string) bool {
|
return func(s string) bool {
|
||||||
return strings.Contains(s, query)
|
return strings.Contains(s, query)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,6 @@ func (s *Server) symbol(ctx context.Context, params *protocol.WorkspaceSymbolPar
|
|||||||
defer done()
|
defer done()
|
||||||
|
|
||||||
views := s.session.Views()
|
views := s.session.Views()
|
||||||
matcher := s.session.Options().Matcher
|
matcher := s.session.Options().SymbolMatcher
|
||||||
return source.WorkspaceSymbols(ctx, matcher, views, params.Query)
|
return source.WorkspaceSymbols(ctx, matcher, views, params.Query)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user