x/tools/gopls: watch file changes on disk
ianthehat opened this issue ยท 26 comments
We cache a lot of information like the AST and typechecking data per file.
If someone changes a file outside the editor, often by doing things with their vcs (update/branch switch is the most common thing mentioned) we currently do not attempt to re-build that information unless it is invalidated by an editor change.
We should be using the LSP handling for workspace/didChangeWatchedFiles to watch all the files we are caching and invalidating them.
It is not clear if we can/should do anything if the client does not support this capability.
Does this not contradict what you said the other day in terms of this being the editor's responsibility?
No, workspace/didChangeWatchedFile, s is the mechanism by which the server can ask the client to tell it when a file changes, which makes it the editors responsibility
Got you. I misconstrued the title of the issue: it's actually that gopls watches these files through the client. Thanks
Just jotting down a couple of notes/questions:
- This presumably includes watching the main module
go.modfile itself too? i.e. it covers the situation where the user adds/drops/changes a requirement - Will the server ask the client to watch files in the read-only module cache?
- Will the server ask the client to watch files in directory-
replace-d modules which are writable? Hopefully yes ๐. Main use case here beinggohackesque workflows
- Watching go.mod - yes
- Watching module cache - undecided, not doing so is more complicated, and possibly fragile, it would have to demonstrate a significant benefit, and we would have to decide if it caused issues when people clear the cache
- Watching replaced files- yes
To update this thread, I am planning to begin work on implementing workspace/didChangeWatchedFile in gopls
I'm sorry, I mistakenly added the Suggested label here. I believe @suzmue is still working on this.
Ok, I am working on this one.
Change https://golang.org/cl/186097 mentions this issue: internal/lsp: fix watched file protocol constants
Change https://golang.org/cl/190857 mentions this issue: internal/lsp: start handling watched file change events
As discussed on the golang-tools call. If we are counting on the clients sending the workspace/didChangeWatchedFile event we need to make sure that the major clients actually handle this well.
There have been extensively documented and long-running issues in VSCode with file-watching. These are not Go-specific but rather with the editor itself. Despite an "experimental" new file-watcher being implemented this is still something that hasn't been addressed. Regardless of the non-Go-specificity this has notable knock-on effects on Go projects part of larger code-bases where gopls would be relying on the editor to keep track of changed files.
One entry-point to the nebula of GH issues related to this is microsoft/vscode#59679.
Change https://golang.org/cl/193121 mentions this issue: internal/lsp: start handling watched file deletes
Change https://golang.org/cl/195537 mentions this issue: internal/lsp: start handling watched file creates
A reminder for an optimization that needs to be added: We should cache a mapping of directories to file URIs to speed up file creation.
@stamblerre what's the latest status on file watching support in gopls?
I'm wondering if we can remove the workarounds we have in govim.
Thanks
It should be coming soon, but not in time for the next gopls release. I've been doing a bit of refactoring to get it to fit in with the rest of the codebase, but the work for this is not yet complete. I will update here when it is.
Not sure if it was intentional, but the options refactoring ended up enabling file watching be default in gopls.
Yes, that actually was (I know it doesn't make much sense since it doesn't work yet). I just want to eliminate that option altogether, since I think it will become very difficult to investigate issues if we have multiple modes of updating files. I'm aiming to get the final few CLs out in the coming days.
Change https://golang.org/cl/214277 mentions this issue: internal/lsp: fix support for watching changed files
File watching now works with gopls at master. The remaining task here is to implement batching at the snapshot level, so that a single snapshot can be invalidated by multiple files instead of a single file.
Change https://golang.org/cl/215902 mentions this issue: internal/lsp: refactor (*snapshot).clone to handle multiple URIs
Change https://golang.org/cl/215906 mentions this issue: internal/lsp: support multiple URIs in (*view).invalidateContent
Change https://golang.org/cl/215907 mentions this issue: internal/lsp: support batched on-disk changes in source.DidModifyFiles
Change https://golang.org/cl/215908 mentions this issue: internal/lsp: batch file changes in didChangeWatchedFiles