Skip to content

Rust Integrated Development Environment (IDE) with VS Code, Neovim, and Emacs

This article describes setting up a Rust language integrated development environment on VS Code [fn:1], Neovim [fn:2], and Emacs [fn:3] [fn:5]. The structure of the article and wording follows Rust in Visual Studio Code and attribution to VS Code contributors for the structure of their documentation.

Setup will be similar across different operating systems (Windows, MacOS, Linux, BSD) since the editors and Rust are available. BSD may require specific instructions or ports for the software mentioned.

The setup uses additional plugins/distributions to make set up easier:

Follow your editor of choice instructions to install on your computer. For Neovim/Emacs, follow the distribution’s instructions after installing the editor.

Learn more about Rust with the The Rust Programming Language book.

Note the shortcut keys in this article assume the editor is configured with the above plugins/distributions which can differ from the default shortcuts. For MacOS, where Ctrl (control) is shown, use the command key. SPC stands for Spacebar.

Install the Rust tools on your machine using the rustup installer, which supports installation on Windows, macOS, and Linux. Follow instructions for your platform, taking care to install any extra tools required to build and run Rust programs.

For more information or if you run into problems, see the Rust installation guide in The Rust Programming Language book.

Install components for rust development using the rustup command line interface and check settings:

Terminal window
# Install rust formatter, linter, and language server
rustup component add rustfmt clippy rust-analyzer
# Check your Rust installation
rustc --version

Description of rust components installed:

  • rustfmt - formatter
  • clippy - linter, code checking and tips to fix issues
  • rust-analyzer - “rust-analyzer is an implementation of Language Server Protocol for the Rust programming language. It provides features like completion and goto definition for many code editors, including VS Code, Emacs and Vim [fn:4]”

Keep your Rust installation up to date with the latest version by running:

Terminal window
rustup update

There are new stable versions of Rust published every 6 weeks so this is a good habit.

Restart any terminal and other development program instances to get the updated PATH.

Rust in Visual Studio Code, Neovim or Emacs

Section titled “Rust in Visual Studio Code, Neovim or Emacs”

Follow instructions depending on which editor you are using:

Within Visual Studio Code, install the rust-analyzer extension and restart VS Code.

Using :LazyExtras, enable the Rust language LazyVim extra. Restart Neovim and run :Mason to download other dependencies.

Add the rust language module under languages in Doom’s init.el add (rust +lsp +tree-sitter). The +tree-sitter flag is optional and requires tree-sitter installed.

The rustup install includes the full Rust documentation set locally installed on your machine by running:

Terminal window
rustup doc

The Rust documentation, including The Rust Programming Language and The Cargo Book, will open in your local browser so you can use it offline.

Follow Hello, World! - The Rust Programming Language in your editor and use Cargo, the Rust package manager in the next tutorial Hello, Cargo! - The Rust Programming Language.

In the two tutorials, all commands can be run on the terminal or use the editor’s terminal or shell command/task runners. Each editor will have their own way of running the program, here are examples:

  • VS Code: use terminal, cargo run
  • Neovim: :!cargo run
  • Emacs: M-x compile cargo run

There are other ways depending on the editor or use the terminal.

rust-analyzer gives features through the Rust language server giving detailed code information and smart suggestions. In VS Code, this feature is called IntelliSense and Neovim/Emacs may call them Language Server Protocol (LSP) information and features.

When you first open a Rust project, rust-analyzer’s progress can be seen in the editor, usually in a status area like the bottom left or messages buffer. Wait until rust-analyzer has completely reviewed your project to use the language server’s features.

One of the first things you may notice is rust-analyzer providing inlay hints to show inferred types, return values, named parameters in light text in the editor like the occurance of the word String in the example below.

let mut guess: String = String::new();

Hovering on any variable, function, type, or keyword will give you information on that item such as documentation, signature, etc.

Shortcut keys:

Feature VS Code Neovim Emacs
Documentation/Hover Mouse or cursor hover K K

In VS Code, hovering can be done with the cursor and mouse. Neovim and Doom Emacs can use the Hover/Documentation key K in normal mode like Vim’s K to look up documentation for the item at the cursor.

You can also jump to the type definition in your own code or the standard Rust libraries using the hover in VS Code or Neovim/Doom Emacs gd for go to definition.

Feature VS Code Neovim Emacs
Go to definition Mouse or cursor hover gd gd

As you type in a Rust file, completions give you suggested completions and parameter hints. The completions are specific to packages installed in the editor.

  • VS Code - IntelliSense
  • Neovim/Doom Emacs - Completion packages

Completions will use things like context of the file and its language as well as other keywords, file context, and other completions you have configured.

Completions can also be triggered manually:

Feature VS Code Neovim Emacs
Completion (Manual trigger) Ctrl + Space Ctrl + Space M-x cape-<depending on completion>

These completions are determined looking at files and content and are would be separate completions from ones that may come from artificial intelligence integration to the editors.

In other words, the completions do not use artificial intelligence. Completions may use a combination of editor’s understanding of the text, programming language (for example functions, variables), dictionary words, files, code snippets and other configured items in the editor.

rust-analyzer is able to use semantic syntax highlighting and styling due to its understanding of source code.

In VS Code, for example mutable variables are underlined in the editor.

Features to move through code are available in the context menu and/or functions of the editor

Code navigation feature VS Code Neovim Emacs
Go to Definition F12 gd gd
Peek Definition/Documentation Alt + F12 K K
Go to References Shift + F12 gr SPC c D
Show Call Hierarchy Shift Alt + H footnote-cn1 lsp-treemacs-call-hierarchy
Go to Symbol in File Ctrl + Shift + O SPC s s SPC s i
Go to Symbol in Workspace Ctrl + T SPC s S SPC c J

footnote-cn1:

:lua vim.lsp.buf.incoming_calls()
:lua vim.lsp.buf.outgoing_calls()

Each editor may have further useful code navigation like search symbol in open files/buffers.

The Rust toolset includes linting, provided by rustc and clippy, to detect issues with your source code.

The rustc linter is enabled by default and detects basic Rust errors and clippy will provide more tips.

Clippy can be used manually to check files in the current project root directory with:

Terminal window
cargo clippy

To enable clippy integration in rust-analyzer, change the Rust-analyzer > Check: Command (rust-analyzer.check.command) setting to clippy instead of the default check. The rust-analyzer extension will now run cargo clippy when you save a file and display clippy warnings and errors directly in the editor and Problems view.

When the linter finds errors and warnings in your source code, rust-analyzer can often provide suggested Quick Fixes (also called Code Actions), which are available via a warning or indicator (light bulb in VS Code) editor. Open available Quick Fixes with:

Feature VS Code Neovim / Emacs
Code action fix Ctrl + . SPC c a SPC c a

Due to rust-analyzer’s semantic understanding of your source code, it can also do smart renames, across your Rust files. With your cursor on a variable, do rename symbol

Feature VS Code Neovim / Emacs
Rename symbol Rename symbol in context menu or F2 SPC c r

The rust-analyzer extension also supports other code refactor features and code generation, which the extension calls Assists. Examples are:

  • Convert if statement to guarded return
  • Inline variable
  • Extract function
  • Add return type
  • Add import

The Rust toolset includes a formatter, rustfmt, which can format your source code to conform to Rust conventions.

Format your Rust file using:

Feature VS Code Neovim Emacs
Format file/buffer Shift + Alt + f SPC c f SPC c f

You also have the option to run the formatter on each save using VS Code settings Editor: Format on save and Neovim/Emacs distributions can be configured to format on save.

Each editor will have different debugging flows.

Install one of two language extension with debugging support:

Neovim Debugging provides an overview of debugging in Neovim.

Install and run LLDB. See example commands at GDB and LLDB Snippets - GDB and LLDB Debugger Snippets.

Feature VS Code Neovim Emacs
Debug Rust Analyzer: Debug SPC d r

Features mentioned above can be configured like inlay hints, semantic syntax highlighting, linting commands, and others.

Each editor can configure the features in settings like VS Code’s settings / settings.json, Neovim LazyVim’s options.lua, and Doom Emacs’ config.el files.

You can learn more about rust-analyzer’s semantic syntax customizations in the Editor features section of the rust-analyzer documentation.

This article explains the rust-analyzer features with each editor. See the details in the Rust Analyzer extension User Manual and see latest features/bug fixes for rust-analyzer at CHANGELOG.

If you have any issues or feature requests, log them in the rust-analyzer extension repository.

See the References section below for links to each editors’ page on Rust support including dealign with common issues and install problems.

Description of IDE functions to Emacs packages from Doom Emacs rust module [fn:3] and Robert Krahn’s post about configuring Emacs for Rust [fn:5]

  • Language support: rustic extends rust-mode for highlights, compilation, cargo commands
  • Errors and checking: flycheck used by rustic. See errors and warning with M-x flycheck-list-errors
  • Language Server Protocol (LSP) integration: lsp-mode or eglot integrates with rust-analyzer like rename symbols, code actions to fix issues, type hits
  • Completion: company-mode, vertico and others
  • Snippets: yasnippet adds common language code snippets
  • Debugging: dape, dap-mode, or M-x gdb (Emacs GDB Graphical Interface) for gdb and lldb integration