The solution at the moment is to close/re-open the project. This is not ideal so I am looking to add a trigger to restart the LSP server when ever a file is created or deleted in VSCode. Does anyone see any issue with doing this apart from it being a bit of overkill just to get a file registered with the server. This won't catch new files added via other methods, like updating from git.
When a solution is implemented in SourceKit-LSP will I still be expected to send workspace/didChangeWatchedFiles messages or will SourceKit-LSP have its own file system watcher.
I just put together a rudimentary implementation of file watching in SourceKit-LSP apple/sourcekit-lsp#443, which reloads the entire package when a new file gets added. It’s still sub-optimal but I’d rather handle it on the SourceKit-LSP side than have the VSCode plugin restart the LSP server. Maybe we’ll be able to improve from there.
Regarding file watching, I found the following in the LSP spec:
Servers are allowed to run their own file system watching mechanism and not rely on clients to provide file system events. However this is not recommended due to the following reasons:
to our experience getting file system watching on disk right is challenging, especially if it needs to be supported across multiple OSes.
file system watching is not for free especially if the implementation uses some sort of polling and keeps a file system tree in memory to compare time stamps (as for example some node modules do)
a client usually starts more than one server. If every server runs its own file system watching it can become a CPU or memory problem.
in general there are more server than client implementations. So this problem is better solved on the client side
Since I don’t fancy implementing file watching in SourceKit-LSP, I’d like to stick with the LSP spec’s recommendation of relying on the client for file watching. If I understand the spec correctly, the client is also supposed to send change notifications for files added e.g. by git.
Using this file watcher extensively in https://carton.dev, I personally found it quite buggy. It can't watch separate files, only directories, and I think there also some issues with how it behaves on latest Big Sur and maybe even Monterey? Still have to thoroughly investigate this breakage. But any attempts to watch a specific file with it, like Package.swift, failed for me, I only had limit success with watching the whole Sources directory with subdirectories in a given Swift project.
Still better than nothing I suppose. Having this LSP bug fixed would unblock me from using Swift outside of Xcode, since the requirement to restart the whole IDE every time a file is added or removed is, to put it mildly, outrageously annoying.
That's great Alex. I'm happy to send the didChangedWatchedFiles messages so you shouldn't need a file system watcher. The only issue I see here is that every editor client that uses sourcekit-lsp will have to send these messages. VSCode makes it fairly easy. I don't know what it is like for other IDEs though.
Is there a server capability I can test for, that will indicate the didChangedWatchedFiles are being processed? I would like to fall back to the restart server on new file if these messages aren't being processed.
@blangmuir combined the new file bug with the Package.swift changes not being propagated bug. Does your PR also resolve this.
One minor thing to note as well. If I have a workspace with multiple folders and I move between files which are in different folders I am restarting the server to point to the folder for the new file. Does sourcekit-lsp support multiple folders, so I can avoid this?
Ok Alex I built a version of sourcekit-lsp from your PR and tested it. Here is what I found
VSCode does all the client work. I don't need to send any didChangedWatchedFiles messages because it does this for me as long as the server returns workspace/didChangedWatchedFiles as a capability, which it is. This answer my question above about recognising a server which supports this.
You request to only watch for adding of files. You will need to watch for removal of files as well.
You are watching for all file changes ** including changes to the .git folder, and build files in the .build folder. Perhaps you should limit your watch to **/*.swift.
Finally it doesn't seem to work. The client is sending the correct messages but I still don't get file completion in a new file.
Sorry my bad it is working. I was using a call in the vscode language client to catch whether workspace/didChangeWorkspaceFiles was being registered as a capability. In doing this I managed to disable the feature on the client side.
Allowing the client to pass every file added/deleted can produce a lot messages to the server in a large project. Maybe it isn't an issue, I guess time will tell.
I noticed your PR has been merged . I hope it can make it into 5.6. On bugs.swift.org this bug was merged with the updates to Package.swift not being propagated bug. As I understand it your PR doesn't currently resolve that issue. Will there be another PR to resolve that issue?
I didn’t have the time to listen for changes to Package.swift yet, even though it should just be about writing a test case and verifying that VSCode actually sends the change notifications when we expect them. I hope, I’ll get to it in the next week or so. Unfortunately, with the Swift 5.6 release winding down, I think that change won’t make it into the release anymore, though. If you want to hot fix this in the VSCode extensions, I would suggest that you send a file created notification followed by a file deleted notification for some arbitrary file whenever you detect changes to Package.swift.
No update to the extension is required. VSCode does all the work in the background, if the LSP server says it supports the workspace/didChangeWatchedFiles message then VSCode will send the relevant messages.