-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: workspace/didChangeWatchedFiles RegisterCapability globs are too broad #41504
Comments
I think we can ignore any of the directories that match these cases: https://github.com/golang/tools/blob/ccabf82fa1aef57afc4686de4b7881718f7b7d27/internal/lsp/cache/view.go#L662. Ignoring something like |
When you say "we", do you mean
As I explained in the original description, the advice with |
Yep, sorry for not being clearer - I linked that function to show the different cases that we know the Go command ignores and that we could also ignore in the GlobPattern.
Yep--I thought you might be asking for an alternative method of ignoring it. |
@stamblerre I'm very unlikely to get to this for some time unfortunately. So please feel free to offer to anyone else who might be interested in taking this on. Thanks for checking in any case. |
Hello, I am interested in taking on this issue. I took the time to look around and run some tests on my own, and it appears that the glob patterns are not flexible enough to match recursively while excluding the pattern the go command excludes ( AFAIK, the remaining approach I see is to watch every folder individually (like it's currently done to handle the deletion events on certain clients) with a less restrictive glob, allowing to match subfolder creation in order to update the watches accordingly. Because we're manually iterating through all known folders of the workspace, we can reject the ones that need to be ignored. Here is a snippet to illustrate this explanation: (context: https://github.com/golang/tools/blob/master/internal/lsp/cache/snapshot.go#L674) var dirNames []string
for uri := range s.allKnownSubdirs(ctx) {
// only watch it if it's not to be ignored, starts with _, . or is named testdata.
if !s.IgnoredFile(uri) {
dirNames = append(dirNames, uri.Filename())
}
}
// yes, we're watching a/b/* because we want subfolders creation events to refresh the watcher.
patterns[fmt.Sprintf("{%s}{,/*}", strings.Join(dirNames, ","))] = struct{}{} Ending the glob with a wildcard ( @stamblerre, Is that the kind of solution you had in mind back then? I am unsure about this trade-off, reducing the cost on the client-side with narrower globs but add unnecessary notifications on the server-side. I don't want to create unnecessary noise, so if that's ok I can go on and submit a CL! |
@jhchabran: Thank you so much for doing this detailed investigation! Really appreciate that you've done a deep dive here. I think you are right that we don't want to begin watching everything with the And in fact, I don't think it should be necessary to switch to the |
Thanks for your feedback 🙏 TL;DR: I found out that I missed an aspect of gopls behavior in my tests which prevented me to see why your above suggestion works. Still, there's a slight behavior change, but that may be inconsequential. I kept my original explanation because it showcases the subtle change in question. Original comment, highlights delay in gopls being aware of new files when they are created outside the editor UI
The problem I see here is that AFAIU, we can't know about the file being created in the subfolder learn when using only But if done through the editor (drag and drop, or right-click create a folder then new file), gopls will receive an event from the editor and thus will refresh the watched folders. To be clearer, through my tests, I observed that:
💡 I just discovered while double-checking myself that if I reference somewhere in the code a symbol that has been declared in the newly added @stamblerre I believe that this 👆 must be what I have been missing since the beginning and now everything makes sense. ➡️ With that in mind, and assuming that it's ok to not have gopls be aware of new files in a newly created package until there's a reference toward it (1) then the costly Please tell me if I missed anything! (1) typing the package name followed by a dot in VScode is enough to achieve that |
I'd be interested to test any glob changes with emacs and lsp-mode/eglot as I'm able. Both have had some trouble in the past (see joaotavora/eglot#602 and emacs-lsp/lsp-mode#1979). |
@jhchabran: Thank you for continuing to test out these complicated cases! I didn't realize that those glob patterns wouldn't get file creation events for subdirectories like the It's starting to seem like it would be unnecessarily complicated to get this working, and I bet that other language servers have run into this too. I filed an issue with VS Code to ask how to ignore certain directories in a Glob Pattern: microsoft/language-server-protocol#1210. Let's wait for a response there before moving forward here. Sorry that this issue has turned out to be so complicated! If you'd like to find another issue to work on, that's totally fine and encouraged :) |
Ok, it totally makes sense! I'll wait for some updates on this and will have a look at the other issues in the meantime then 😊👍 @stamblerre No worries, the issue being more complicated than it looked was part of the fun for me, I'm glad that I may have helped to move further on this topic by digging into it. I'm quite curious to see what will they answer on the issue in the eventuality of not having missed anything in what can be done with the glob patterns or elsewhere. I believe the topic had been previously discussed over here microsoft/language-server-protocol#354. |
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?
Given the following setup:
I loaded
govim
.What did you expect to see?
Precise
workspace/didChangeWatchedFiles
globls in anyRegisterCapability
call.What did you see instead?
Side note: the working directory of
govim
(and thereforegopls
) in this case was/home/myitcv/gostuff/src/github.com/myitcv/playground
, so the first and third watchers appear to be duplicates.If I understand the glob spec,
**/*.{go,mod,sum}
means "all.go
,.mod
and.sum
files in all subdirectories".The recursive descent into subdirectories does not stop at directories whose names start with
.
or_
, or those that containgo.mod
files. This can, and does, make this watch very expensive if, for example, you have a directory likenode_modules
that contains lots of files that are and always will be totally irrelevant togopls
(the advice here is to put ago.mod
in that directory).I suspect this situation is somewhat a function of the LSP spec, but can these globs be made more specific in some way?
An approach to
.gitignore
patterns would work for example.cc @stamblerre
FYI @leitzler
The text was updated successfully, but these errors were encountered: