-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Extend VFS to watch files #433
Comments
Shouldn't we use the LSP capabilities for that? The LSP spec says
|
It looks like it wouId be easier that way. I can try to implement it. It looks like it's just adding a new block on https://github.com/rust-analyzer/rust-analyzer/blob/44e42edc8b7729716e0b410ced2e96c33573e2c0/crates/ra_lsp_server/src/main_loop.rs#L315-L396 |
I've saw that, and I explicitly disagree :-) I think we should primarily rely on our own file-watching implementation, for the following reasons:
I think that "multiple servers" should not apply for rust-analyzer: a single instance of the server should handle many separate projects simultaneously (it makes sense, because deps & stdlib will most likely be shared anyway). I fully understand that creating a correct, performant & cross-platform file-watching service is an enormously hard task, but that's actually the perfect problem to solve in Rust :-) I think (in the long-run) it makes sense for VS Code to switch to Rust for the implementation of this core component :) In the short run, a "mostly correct" implementation will actually give us 80% benefits I guess? We could also start with an LSP-based impl and switch to native one later, but I'd rather avoid that route, because it will remove the initiative to write the native impl. |
After reading your reasons I agree. Also there's at least another issue https://code.visualstudio.com/api/references/vscode-api#2261:
so it wouldn't be possible to watch But since it didn't look too difficult I implemented it here https://github.com/vemoo/rust-analyzer/tree/lsp-file-system. |
@vemoo I'd still prefer to start with |
Ok, I will start working on a bare-bones impl with |
It's mostly implemented here https://github.com/vemoo/rust-analyzer/tree/vfs-watch.
There's still something that's not quite working. I will investigate further, maybe I'm missing something. |
Interesting! I wonder if it is possible to make both scanner and watcher to use the same channel to output events. That is, I originally envisioned that |
I will try to implement that.
I figured something like that, because of how
|
I've started looking at what's needed to use the same channel for scanner and watcher events and I think I have an idea of how it can be done.
enum Task {
AddRoot(...),
WatcherChange(...)
}
This way we can send |
The
Yep, that would be the ideal solution. The simple solution would be to store
Yes, that's precisely the intention. We probably could do watching in the |
I've made some progress here. To be able to filter watcher events I've turned pub(crate) enum Task {
AddRoot {
root: VfsRoot,
path: PathBuf,
filter: Box<Fn(&DirEntry) -> bool + Send>,
},
LoadChange(crate::watcher::WatcherChange),
} And added another case pub enum TaskResult {
AddRoot(AddRootResult),
HandleChange(WatcherChange),
LoadChange(Option<WatcherChangeData>),
} That way on There's another
But unless we keep separate watchers per root we will have to reload all the roots. We could remove all files (except ones with overlay) and then send I also figured out why the watcher thread wasn't shutting down. It was a bug in |
I've looked through the changes and they look good to me! I think it's OK to not handle
Awesome! I bet it was tricky to debug that! And it's cool that we actually hit that bug: this means that we do put some effort on our side to cleanup the threads properly. I think it's ok to just let that thread hang for the time being. |
The problem is that the |
Note that Notify is more "passively maintained" than "frozen". If you need changes/features (or fixes, as you've seen!) and can contribute an impl I'll be more than happy to merge, even for breaking changes (with a higher threshold, tho). I'm just not going to spend lots of time on it. Current estimation is that I won't release v5 before async/await is in stable rust, but that could change. |
Awesome! Thanks for chiming in, @passcod ! |
Fixed! |
Currently, VFS reads files once at startup, and then only uses text-editor notifications to change the state of files.
This works surprisingly well in practice, but we do miss some file system changes (when, for example, switching branches in git). We should add file-system watching to vfs.
This is tricky in itself, and it is not made easier by the fact that the main filesystem-watching library, https://github.com/passcod/notify/, is transitioning from v4 (which is frozen) to v5 (which is not released yet). v5 does not seem like it would be done in the nearish term, so we should perhaps rely on v4 for the time being.
The code for vfs is here:
https://github.com/rust-analyzer/rust-analyzer/blob/53ffa2a030be52ad6ddcf3c038f08c337894fbe7/crates/ra_vfs/src/lib.rs
The text was updated successfully, but these errors were encountered: