zed-industries / zed

Code at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
https://zed.dev
Other
49.4k stars 3k forks source link

Rust: Integrate with bacon - Proper automatic checks/recompilation for (larger) workspaces #15912

Open DragonDev1906 opened 2 months ago

DragonDev1906 commented 2 months ago

Check for existing issues

Describe the feature

Motivation (and my workflow)

I'm working in a larger workspace, where the defaults for rust-analyzer are near useless (due to it taking so long). The Zed Documentation even acknowledges this, providing a really useful but in my opinion limiting suggestion. I chose to only disable --workspace because I still want cargo check to run when I save a file.

"check": {
  "workspace": false
}

Unfortunately this has the big downside that when I edit crate A zed/rust-analyzer checks crate A, but doesn't check crate B which has A as a dependency, which isn't really useful if A is an internal dependency. To avoid having this problem I run bacon in the background, which watches for file changes and runs cargo check (or clippy) against all crates that are affected by a change. In the example above it checks A and B but no crate that doesn't (directly or indirectly) depend on A.

I believe Zed could become a lot better by integrating (or working together) with this existing tool.

To do that it also runs cargo check once in the beginning for the entire workspace.

Proposed feature

I'd love if Zed could include or at least work with bacon. Either by:

I'd suggest one of the first two approaches. Note that this can just as well be used for smaller projects for which rust-analyzer works well enough (or enabled/disabled in the settings). The first two are easier to implement and maintain.

The ideal solution (in my opinion)

Note that I'm still using rust-analyzer, but I find bacon's approach to re-checking and error printing a lot more useful.

Alternative considered

Zed could (as mentioned above) re-implement the decision which crates to recompile, but I think that adds unnecessary complexity/overhead when such a tool already exists, which has additional features like selecting between cargo check, cargo clippy, cargo test, ... (in the newest version even pausing the checking when working on a larger set of errors.

Additional notes

If applicable, add mockups / screenshots to help present your vision of the feature

Here I'm running bacon in a terminal in Zed, and the output is, even for this simple error, (in my opinion) a lot more readable than the diagnostics from rust-analyzer or rustc. Imagine having this output in the diagnostics view and have it editable. Or at the very least have the link in bacon's output be clickable, going directly to the source file.

2024-08-07-171615_1084x1306_scrot

maan2003 commented 1 month ago

what if we filter diagnostics to only rustc source, the last diagnostic in zed is more readable than terminal IMO

DragonDev1906 commented 1 month ago

That would also work, as that's also what bacon's output is based on.

Though personally I'd still use bacon in that case, even if it means one more click to edit it, as my main issue with the built-in diagnostics isn't just the way errors are displayed:

But the example above is also one of the simplest cases, where everything is in one file. Consider the following: 2024-09-18-142550_2559x1307_scrot

The diagnostics pane shows the necessary information, but IMO fails in two things:

The way these are displayed is of course subjective, but rust has so nice error messages, which are easy to read and act upon.

For me this "only printing part of the information" combined with rust-analyzer being really slow or not working properly makes the diagnostics window almost useless to me (for Rust). Hence the suggestion of integrating with bacon (perhaps in addition to showing a (filtered) list in the diagnostics pane as it is now).

jansol commented 1 month ago

I would certainly love to see this integrated, along with an Xcode-style inline display mode. The Easy :tm: solution here would be making bacon act as a language server. Then it would be possible to create an extension for running it, and to opt out of rust-analyzer via zed's configuration. I haven't seen any mentions of such efforts or requests in the bacon repo though.

Bacon allows you to pause at any time, something you cannot do with the built-in diagnositcs as far as I know

LSP allows canceling requests AFAIK. Not sure how close that comes to what you are referring to?

DragonDev1906 commented 1 month ago

I haven't seen any mentions of such efforts or requests in the bacon repo though.

Probably because the main goal of bacon is being a background process that shows warnings/errors whenever it finds them, rather than being asked by a different process to do something.

I think the closest to a LSP in bacon is the export file, the format of which can be configured: https://github.com/Canop/bacon/blob/c5cd5a72d3cadab15283a6f409db48edda725e3c/website/docs/config.md?plain=1#L127

LSP allows canceling requests AFAIK. Not sure how close that comes to what you are referring to?

I don't know much about how Rust-Analyzer does things. Bacon (as of the latest version) effectively does the following:

Previously checks where canceled automatically/immediately when you changed something else on_change_strategy = "kill_then_restart", which wasn't ideal.

jansol commented 1 month ago

Probably because the main goal of bacon is being a background process that shows warnings/errors whenever it finds them, rather than being asked by a different process to do something.

It could still compute these in the background, the LSP part could be a relatively simple shim that requests the background process to resume (if paused and there have been changes) and to return the cached diagnostics when it has recent enough ones.

bbb651 commented 1 month ago

Luckily an LSP implementation already exists! https://github.com/crisidev/bacon-ls

I might try to create a plugin for it. Either way I don't think special support within Zed is a good idea in general, and in this case the diagnostics mutlibuffer with an LSP is already what you're asking for.

nullstalgia commented 4 weeks ago

Even if there isn't a dedicated plugin for it, a mention on the docs on how to get the two to play nice would be great.

While I really like Zed's diagnostics tab, it doesn't prioritize putting Errors above Warnings, and I can't move it outside of Zed itself. Bacon feels like a good in-between, since it can be on a dedicated window/monitor, but the aforementioned cargo check issues make it feel not-so-seamless.