-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/tools/gopls: support advanced query syntax for Symbol #37237
Comments
Per #37236 (comment), we should also add a module scope, again parameterised by file, to limit the search scope to the module containing the file. |
To make this request more formal I'd like to sketch out a potential query syntax. It is based on the popular In the text that follows, the term "item" refers to what we are matching against (noting that more information/context is returned in Search syntaxUnless otherwise specified via an option (see below),
To be explicit, OptionsOptions are provided as special search terms in the form
ExamplesWe assume for the following examples that:
Example 1A query of Example 2A query of Outstanding questions
|
Change https://golang.org/cl/227677 mentions this issue: |
DO NOT REVIEW DO NOT SUBMIT * Add config option for SymbolMatcher * Fully qualify symbols and match against fully-qualified symbol * Define and implement workspaceOnly and nonWorkspaceExportedOnly search options Fixes golang/go#38273 Updates golang/go#37237 Change-Id: Ie58ae992bf2d22673c3daa2c495c15279a1fa54b
DO NOT REVIEW DO NOT SUBMIT * Add config option for SymbolMatcher * Fully qualify symbols and match against fully-qualified symbol * Define and implement workspaceOnly and nonWorkspaceExportedOnly search options Fixes golang/go#38273 Updates golang/go#37237 Change-Id: Ie58ae992bf2d22673c3daa2c495c15279a1fa54b
I experimented with fzf-like syntax in http://golang.org/cl/248418, and it was very straightforward to add. Furthermore, it is backwards compatible with our current fuzzy matching: any query containing Regarding the rest of the proposal, supporting things like So because syntax like |
The only one comment to add is that the approach I've experimented with in https://go-review.googlesource.com/c/tools/+/227677 makes no additional requirements of the LSP client, only the editor/user. You're quite right: there is no expectation that a user would ever type one of these options interactively, rather that via a user-defined custom key mapping, the editor user would augment a typed search query with certain options. Either way we end up exposing the end user to some sort of API, namely the structure of the options to specify a particular type of search/scope. Whilst my approach in this CL works in a setting like Vim where there are powerful key mapping capabilities, I quite acknowledge it's not guaranteed to work in all editors. As such a proper API might well be more appropriate. But that might place a requirement on each LSP client to support it (I have no experience with non-standard requests so can't comment on the merits one way or the other). Hence it felt like, for the very short term, this approach provided a nice, purely opt-in way to experiment with the types of options that would be appropriate, with zero impact on existing clients, editors, users etc. |
Having discussed this at length with @myitcv today, I'm starting to come around to the idea of supporting at a subset of the advanced filters proposed above within the workspace symbols request. In particular, having seen that the workspace symbols RPC can get noticeably slow in very large projects, it could generally be helpful to expose a mechanism that limits the scope of packages that are walked when looking for symbol matches. Limiting to the current workspace, module, or package seems natural. We could of course do this via configuration rather than a dynamic query field. But in that case we'd be supporting the complexity of implementing the filter anyway. How much more complexity is added to support parsing I'm less convinced by the argument that users will regularly want to bounce back and forth between searching within all packages, within the current package, and within the current module. In my experience, as long as the symbols request is fast, I have no difficulty jumping to my desired symbol across all packages. If I want to go to the So in summary: I think we should do a cost-benefit analysis of a subset of the proposed syntax. Specifically, how much complexity would it add, and how much our users would benefit from it. Regarding complexity, I think the following filters would not add much, the reason being that they only affect the set of packages walked, not the symbol search itself. It would be pretty easy just to put together a CL to do this (sans tests) that we can consider.
Regarding benefit, I think we should try to put some numbers behind the performance argument. I wrote a benchmark in CL 250798 that can be used for this: let's pick some known large repo (Kubernetes?) and benchmark different queries. It's worth caring about anything above ~100ms. I'd be happy to do this work myself, though I won't get to it for at least a couple weeks. But fair warning, we may look at all this and decide it's not worth it, given all of our other priorities. |
FWIW, I'm implementing an coc.nvim plugin that lists tests of current file using However, in most cases, I found myself wanting to locate the tests in the current package, not just the current file. With this |
Things have evolved a bit since we last talked about this. Gopls now has much better support for custom commands using workspace/executeCommand. I'd rather build a custom command for package symbols than try to build an API on top of workspaceSymbols: workspaceSymbol results are interpreted by many different LSP clients, who do things like apply additional filters. @hyangah could VS Code also use a PackageSymbol or more generalized SymbolQuery API? Is there something to design here? |
Generalised SymbolQuery as a command would be great. My feeling is go's package scope creates quite a few things that's specific to Go. E.g. finding all the methods of a struct: it would be in the current module, not a DocumentSymbol query. On a similar issue (maybe worth another issue): Query the package's full name and partial name of current buffer. I'm using |
@findleyr time to resurrect https://go-review.googlesource.com/c/tools/+/315669 (This was part of an unfinished attempt to demo Package Outline View in vscode-go) |
@jackieli-tes I think we're generally open to offloading work to gopls using custom commands. However, we want to avoid the proliferation of commands with overlapping functionality. Could you please file a separate issue for the requirements of what you're using In this issue, it would be great if you could specify your requirements for a SymbolQuery API, in terms of arguments and results. (another side note: since this issue was originally opened, our workspace symbol queries have gotten up to 40x faster depending on the query: we keep a symbol table active in memory, so some of the constraints have changed). |
Thanks @findleyr for the info. I quite like the suggestions in the link especially around using a light weight memory representation on the symbols. I don't agree with the external plugin approach though. I might understand it wrong, but I reckon either way, it should come out as an LSP command: LSP clients e.g. coc.nvim already have easy ways to invoke the command. Integrating with the editors would be easier. Filled the retrieve package info command issue: #51490 Also filed the package symbols proposal: #51492 |
New feature. It shows all public symbols inside a go package with a side panel. Also refer golang/go#37237 for some workaround * add side_panel for go package * Add command GoPkgInfo * multi lines hint * allow refresh when buffer write happed * remove node of receiver * update treesitter queries for better panel display * variadic args
Coming back to this: I think various users and clients struggle with the fact that the LSP concepts of "workspace" and "document" do not align nicely with go package/module/workspace boundaries. I think we should revisit adding a custom command that provides the query search syntax that we want, and let |
I can't say I'm fully appraised on the pros/cons of putting this in a separate command vs overloading Also, give my exploration/experimentation detailed above it appears clear to me (at least) that such a command will only ever work with editor support: a user will never type in the long-form qualifiers that alter the scope of a given search to be either file, package, module, workspace etc. As a Vim user, such editor support would be achieved via a Vim command that adds the qualifier based on the current buffer's filename etc. As such from a Vim perspective, it doesn't per se matter whether this is an existing command or a new one, because there will be some automation to add these scope qualifiers on top of anything the user types. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
This is a request/proposal more than an issue.
We were discussing with @findleyr a means by which symbol search can be made more useful (in Vim). With #37236 fixed, the existing Symbol method will return matches from within the workspace (main module). But a fairly common query is to find symbols matching the query within the "current" package, where "current" is defined by the file within which the cursor is located. i.e. I want to jump to the definition of the method
(*T).M
.Because the editor/client knows nothing about packages, I think this will require a query similar to the following. Imagine we are searching using the term
hello
, with the cursor in the filemain.go
gopls
would then translate the file URI to a package and suitably constrain the results.cc @stamblerre @findleyr
FYI @leitzler
The text was updated successfully, but these errors were encountered: