I started exploring Rust as a programming language. I quickly ran into issues with code completion in Emacs. I fixed it, read on to learn how I did that!

In order to have code completion in Emacs for Rust you will need a tool called racer.

As I write this the latest racer version is 2.1. Sadly it has a bug. It does not complete source code in external crates. If you build anything worth using you will probably be using external crates and you will want to have code completion in your Emacs.

First, there is an issue logged on GitHub, #981. It was quickly resolved, which is awesome, but that means we need to install racer from source. Luckily the steps to build your own version are easy:

$ git clone https://github.com/racer-rust/racer.git
$ cd racer; cargo +nightly build --release
$ cp target/release/racer ~/.cargo/bin 

The other tool that is needed is cargo. This is part of the standard Rust distribution and everyone already has it. The thing is that racer requires the tool to be in the path when it is called. This seems to be due to changes to support the 2018 version of Rust (its use is documented in this issue: #916). To get it into the path of the shell that is used by Emacs it needs to be in the $PATH variable (perhaps also exec-path). To ensure it is there I set it in my init.el:

(setenv "PATH" (concat "~/.cargo/bin:" (getenv "PATH")))

To test your installation restart Emacs and fire up eshell: M-x eshell. I do this from my Rust project so that the directory is correct. Then you should be able to call cargo metadata and you should see a lot of output.

Welcome to the Emacs shell

~/project/src $ cargo metadata
warning: please specify `--format-version` flag explicitly to avoid compatibility problems
{"packages":.... [snip].....

My complete Rust configuration looks like the following at this point. Using the above changes I now have full code completion, syntax checking and cargo integration working.

(use-package racer
  :ensure t
  (add-hook 'racer-mode-hook #'company-mode)
  (setq company-tooltip-align-annotations t)
  (setq racer-rust-src-path "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src"))

(use-package rust-mode
  :ensure t
  (add-hook 'rust-mode-hook #'racer-mode)
  (add-hook 'racer-mode-hook #'eldoc-mode)
  (setq rust-format-on-save t))

(use-package cargo
  :ensure t
  (setq compilation-scroll-output t)
  (add-hook 'rust-mode-hook 'cargo-minor-mode))

(use-package flycheck-rust
  :ensure t
  (add-hook 'flycheck-mode-hook #'flycheck-rust-setup)
  (add-hook 'rust-mode-hook 'flycheck-mode))

Tags: , , ,