rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

Allow individual crates to specify server watching in rust-project.json

Open Wilfred opened this issue 7 months ago • 5 comments

Currently file watching is a global setting, e.g. using the following in VS Code's settings.json:

"rust-analyzer.files.watcher": "server",

However, we'd like the ability to specify file watching on a per-crate basis. This would be useful for projects built with buck, where generated code is written to ./buck-out/gen/abc123/__project/lib.rs. VS Code doesn't notify r-a when this file changes (even if the user has it open), so we get stale go-to-def and code completions when the generated file has changed on disk.

Previous discussions: #556 and #433 for file watchers in general, #16913 for file watching differences between operating systems, and #19387 mentions that VS Code doesn't send all notifications. I think there was an issue discussing VS Code not sending notifications in specific circumstances, but I can't find it.

@davidbarsky's view is (I think) that this is a reasonable addition, and I'm happy to put up a PR if y'all think this makes sense.

Wilfred avatar Jun 02 '25 17:06 Wilfred

So this is a bug in VSCode, and you want to add this setting to workaround it? I don't object if the change is contained.

ChayimFriedman2 avatar Jun 03 '25 04:06 ChayimFriedman2

Why exactly is setting the global setting not an option?

Veykril avatar Jun 03 '25 06:06 Veykril

My current repro looks like this:

(1) Open myproj/main.rs, ./buck-out/generated/mod.rs, and the foo.thrift file that mod.rs is generated from.

(2) Add a new field to a struct in foo.thrift and save, then make a change to myproj/main.rs and save. Observe that ./buck-out/generated/mod.rs is updated on disk (as a side effect of rust-analyzer.check.overrideCommand running a check build).

(3) Observe that I'm not offered this new struct field in myproj/main.rs code completion, regardless of the value of rust-analyzer.files.watcher.

(4) Switch to the ./buck-out/generated/mod.rs file in VS Code, switch back to myproj/main.rs, observe that code completion now knows about my new struct field.

Overall it feels like generated code should probably have a separate watch mode rather than requiring a global setting (especially since "server" for watcher doesn't help). It's going to be modified outside of VS Code regularly.

Wilfred avatar Jun 03 '25 15:06 Wilfred

Overall it feels like generated code should probably have a separate watch mode rather than requiring a global setting (especially since "server" for watcher doesn't help). It's going to be modified outside of VS Code regularly.

I am confused, if changing it so "server" doesn't help, then how is what this issue proposes going to help? It sounds like neither client or server mode helps you here, so why would allowing this setting to be changed on a per crate basis make those modes suddenly work?

Veykril avatar Jun 04 '25 07:06 Veykril

Sorry, I didn't have a great repro when I first wrote this issue. I was thinking of a rust-project per-crate setting that just made rust-analyzer aggressively poll or use inotify to pick up changes to the generated files.

I will also trace through the "server" mode logic to see if it's just a limitation there that we can fix.

Wilfred avatar Jun 04 '25 10:06 Wilfred

Some additional debugging notes:

The server file watching mode requires your file to belong to the current workspace, i.e. is_workspace_member: true in JSON.

Adding debug logging to the inotify logic, I think I'm getting a Remove event and nothing else:

[crates/vfs-notify/src/lib.rs:112:41] &event = Event {
    kind: Remove(
        File,
    ),
    paths: [
        "/home/wilfred/scratch/buck-out/gen/abc123/__project/mod.rs",
    ],
    attr:tracker: None,
    attr:flag: None,
    attr:info: None,
    attr:source: None,
}

Possibly the code generator is treated as a deletion and a creation of the file, and r-a stops watching after the deletion. I'll dig further.

Wilfred avatar Jun 23 '25 09:06 Wilfred