rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
13.84k stars 1.53k forks source link

IDE functionality in unsaved examples #17432

Open mqudsi opened 4 weeks ago

mqudsi commented 4 weeks ago

While your basic GUI editor like VS Code can’t do it, the majority of command line editors support providing the path a file will be saved under prior to actually writing out the buffer upon first save.

I realize this could be an issue with the LSP client, so please correct me if so, but in cases where the user creates a buffer associated with an unmaterialized path, could RA use that path instead of showing errors about the buffer not being part of the crate tree?

eg :e examples/foo.rs will currently trip up RA until a :w is issued, but does that need to be the case (assuming the client sends the path along)?

roife commented 3 weeks ago

Currently, some functionalities in r-a require the file to be saved (e.g., flycheck). Therefore, if the file is not saved, many features of r-a will not be available.

mqudsi commented 3 weeks ago

There is no way that saving it to a temp directory could be hacked around to suffice?

flodiebold commented 3 weeks ago

Uncreated files can have a path, that's not the problem. If you e.g. do :e foo.rs and add the mod foo declaration, things should work fine. The case of examples/foo.rs doesn't work because RA runs Cargo to learn about project structure like examples, and Cargo will only see files on disk. (flycheck also of course doesn't work, but isn't relevant for IDE functionality except diagnostics.)

mqudsi commented 3 weeks ago

Yeah, that's more or less what I assumed was the case.

My question is not specific to examples btw, but it is whether or not it is possible to use a heuristic when a file is being edited that's not found in the Cargo project hierarchy. Can a file in examples/ be assumed to be an example and compiled manually as such, a file in bin/ treated as a top-level entry point, and other files treated as if they were in a module accessible by their path (e.g. src/foo/bar.rs would assume the presence of mod foo at the top level and mod bar again at the next level)?

flodiebold commented 3 weeks ago

It's a very different problem for examples/bins and for modules. I think for examples and bins the main problem would be fitting it into the architecture, but if/once we have on-demand project loading it might be pretty doable as a heuristic (it seems pretty similar to that to me). For modules, this already works, if you have the mod declaration in place. Treating loose files that are not officially part of the module tree as if they were (independent of whether they're unsaved or not) is something that has been asked/considered before, but it's a whole other can of worms. There is a reason why making the module structure implicit based on file structure was in the end rejected when it was considered for the 2018 edition, so I don't think it makes sense to unilaterally handle it differently in rust-analyzer; this would lead to a lot of confusion. A possible alternative would be to only treat the file as part of the module tree for IDE functions inside that file, i.e. inside the file you could get completions for super::, but outside it would work like it's missing. But that also wouldn't quite match expectations and would be very hard to implement.