I’ve been getting back into Rust programming for work, and things have changed over the past two years. racer, which I was using for code completion and jump-to-definition, is no longer actively maintained, while LSP and Rustic have appeared on the scene.
A couple weeks ago I decided to set up a fresh Rust config from scratch. It was harder than it should have been, so I’m documenting the final result for others.
Getting the Pre-Requisites
The dependencies should be installed by our Emacs package Rustic:
(use-package rustic)in your config and most stuff gets configured automatically.
… but aren’t. At least, not on OSX.
So let’s start by installing the components we need.
rustup component add rust-src rustfmt clippy rls rust-analysis
I thought this was all I would need, but of course, that was too naively optimistic of me.
It turns out that rust-analysis is not the same as rust-analyzer, and you need the second one. And neither
rustup nor our Rust package actually install it, nor is it available with
cargo install. In fact, you have to manually install it. The Rustic instructions don’t mention this, of course, so I had to spend an hour Googling it.
An issue has been filed about this (and summarily ignored).
Now to the Emacs config. I use
Rustic, which purports to be an upgrade to
rust-mode and claims to set up dependencies automatically (although it doesn’t, which is why we needed the above section).
It doesn’t look like much, but it took me hours to get that right.
eglot, because the alternative,
lsp-mode, was breaking for some of my (simple) Rust projects, and I couldn’t figure out why after a couple of hours of looking into it.
eglot seemed stable, at least.
Here is a post from the maintainer of
eglot explaining why his package is better than
lsp-mode. I agree with it. Personally, my experience with
lsp-mode was awful, but YMMV.
Next, I disabled the automatic code checking, which would run as I typed. This was causing a lot of lag and stutters, all of which was seriously interfering with my programming. This should be an easy thing to turn off, but there’s no option for it. The best we can do is increase the delay; the code checking still runs on save.
Finally, I needed to disable the doc popups in the minibuffer as they were extremely distracting. Again, it took lots of googling to get this right because there was no obvious way to do this.
Looking back, maybe I should have just stuck with
rust-mode. But I am happy with the features I have now: code-completion, jump-to-definition, and syntax-checking on save. They work really well, and after some configuration they don’t get in the way.