mrcjkb/rustaceanvim

github github
lspneovim-0.5
stars 159
issues 12
subscribers 4
forks 4
CREATED

2021-05-11

UPDATED

1 hour ago


Neovim Lua Rust Nix

GPL2 License Issues Build Status LuaRocks

[!NOTE]

Quick Links

Prerequisites

Required

Optional

Installation

This plugin is available on LuaRocks.

Example using lazy.nvim:

{
  'mrcjkb/rustaceanvim',
  version = '^3', -- Recommended
  ft = { 'rust' },
}

[!NOTE]

It is suggested to pin to tagged releases if you would like to avoid breaking changes.

To manually generate documentation, use :helptags ALL.

[!NOTE]

For NixOS users with flakes enabled, this project provides outputs in the form of a package and an overlay; use it as you wish in your NixOS or home-manager configuration. It is also available in nixpkgs.

Look at the configuration information below to get started.

Quick Setup

This plugin automatically configures the rust-analyzer builtin LSP client and integrates with other Rust tools. See the Usage section for more info.

[!WARNING]

Do not call the nvim-lspconfig.rust_analyzer setup or set up the lsp client for rust-analyzer manually, as doing so may cause conflicts.

This is a filetype plugin that works out of the box, so there is no need to call a setup function or configure anything to get this plugin working.

You will most likely want to add some keymaps. Most keymaps are only useful in rust files, so I suggest you define them in ~/.config/nvim/after/ftplugin/rust.lua[^1]

[^1]: See :help base-directories

Example:

local bufnr = vim.api.nvim_get_current_buf()
vim.keymap.set(
  "n", 
  "<leader>a", 
  function()
    vim.cmd.RustLsp('codeAction'), 
  end,
  { silent = true, buffer = bufnr }
)

[!NOTE]

Usage

:RustLsp debuggables [last?]
vim.cmd.RustLsp {'debuggables', 'last' --[[ optional ]] }

:RustLsp runnables [last?]
vim.cmd.RustLsp {'runnables', 'last' --[[ optional ]] }

:RustLsp expandMacro
vim.cmd.RustLsp('expandMacro')

:RustLsp rebuildProcMacros
vim.cmd.RustLsp('rebuildProcMacros')
:RustLsp moveItem up
:RustLsp moveItem down
vim.cmd.RustLsp { 'moveItem',  'up' }
vim.cmd.RustLsp { 'moveItem',  'down' }

Note: To activate hover actions, run the command twice. This will move you into the window, then press enter on the selection you want. Alternatively, you can set auto_focus to true in your config and you will automatically enter the hover actions window.

:RustLsp hover actions
vim.cmd.RustLsp { 'hover', 'actions' }

:RustLsp hover range
vim.cmd.RustLsp { 'hover', 'range' }

Display a hover window with explanations from the rust error codes index over error diagnostics (if they have an error code).

:RustLsp explainError
vim.cmd.RustLsp('explainError')

:RustLsp openCargo
vim.cmd.RustLsp('openCargo')
:RustLsp parentModule
vim.cmd.RustLsp('parentModule')
:RustLsp joinLines
vim.cmd.RustLsp('joinLines')
:RustLsp ssr [query]
vim.cmd.RustLsp { 'ssr', 'query' --[[ optional ]] }
:RustLsp crateGraph [backend [output]]
vim.cmd.RustLsp { 'crateGraph', '[backend]', '[output]' }
:RustLsp syntaxTree
vim.cmd.RustLsp('syntaxTree')

Run cargo check or another compatible command (f.x. clippy) in a background thread and provide LSP diagnostics based on the output of the command.

Useful in large projects where running cargo check on each save can be costly.

:RustLsp flyCheck [run?|clear?|cancel?]
vim.cmd.RustLsp('flyCheck') -- defaults to 'run'
vim.cmd.RustLsp { 'flyCheck', 'run' }
vim.cmd.RustLsp { 'flyCheck', 'clear' }
vim.cmd.RustLsp { 'flyCheck', 'cancel' }

[!NOTE]

This is only useful if you set the option, ['rust-analzyer'].checkOnSave = false.

Advanced configuration

To modify the default configuration, set vim.g.rustaceanvim.

The options shown below are the defaults. You only need to pass the keys to the setup function that you want to be changed, because the defaults are applied for keys that are not provided.

Example config:

vim.g.rustaceanvim = {
  -- Plugin configuration
  tools = {
  },
  -- LSP configuration
  server = {
    on_attach = function(client, bufnr)
      -- you can also put keymaps in here
    end,
    settings = {
      -- rust-analyzer language server configuration
      ['rust-analyzer'] = {
      },
    },
  },
  -- DAP configuration
  dap = {
  },
}

[!NOTE]

vim.g.rustaceanvim can also be a function that returns a table.

Using codelldb for debugging

For Rust, codelldb from the CodeLLDB VSCode extension provides a better experience than lldb. If you are using a distribution that lets you install the codelldb executable, this plugin will automatically detect it and configure itself to use it as a debug adapter.

Some examples:

If your distribution does not have a codelldb package, you can configure it as follows:

  1. Install the CodeLLDB VSCode extension.
  2. Find out where it is installed. On Linux, this is typically in $HOME/.vscode/extensions/
  3. Update your configuration:
vim.g.rustaceanvim = function()
  -- Update this path
  local extension_path = vim.env.HOME .. '/.vscode/extensions/vadimcn.vscode-lldb-1.10.0/'
  local codelldb_path = extension_path .. 'adapter/codelldb'
  local liblldb_path = extension_path .. 'lldb/lib/liblldb'
  local this_os = vim.uv.os_uname().sysname;

  -- The path is different on Windows
  if this_os:find "Windows" then
    codelldb_path = extension_path .. "adapter\\codelldb.exe"
    liblldb_path = extension_path .. "lldb\\bin\\liblldb.dll"
  else
    -- The liblldb extension is .so for Linux and .dylib for MacOS
    liblldb_path = liblldb_path .. (this_os == "Linux" and ".so" or ".dylib")
  end

  local cfg = require('rustaceanvim.config')
  return {
    dap = {
      adapter = cfg.get_codelldb_adapter(codelldb_path, liblldb_path),
    },
  }
end

How to dynamically load different rust-analyzer settings per project

By default, this plugin will look for a rust-analyzer.json file in the project root directory, and attempt to load it. If the file does not exist, or it can't be decoded, the default settings will be used.

You can change this behaviour with the server.settings config:

vim.g.rustaceanvim = {
  -- ...
  server = {
    ---@param project_root string Path to the project root
    settings = function(project_root)
      local ra = require('rustaceanvim.config.server')
      return ra.load_rust_analyzer_settings(project_root, {
        settings_file_pattern = 'rust-analyzer.json'
      })
    end,
  },
}

Troubleshooting

Health checks

For a health check, run :checkhealth rustaceanvim

rust-analyzer log file

To open the rust-analyzer log file, run :RustLsp logFile.

Minimal config

To troubleshoot this plugin with a minimal config in a temporary directory, you can try minimal.lua.

mkdir -p /tmp/minimal/
NVIM_DATA_MINIMAL="/tmp/minimal" NVIM_APP_NAME="nvim-minimal" nvim -u minimal.lua

[!NOTE]

If you use Nix, you can run nix run "github:mrcjkb/rustaceanvim#nvim-minimal-stable". or nix run "github:mrcjkb/rustaceanvim#nvim-minimal-nightly".

If you cannot reproduce your issue with a minimal config, it may be caused by another plugin. In this case, add additional plugins and their configurations to minimal.lua, until you can reproduce it.

FAQ

Where are inlay hints?

As Neovim >= 0.10 supports inlay hints natively, I have removed the code from this plugin.

To enable inlay hints in Neovim < 0.10, see this discussion.

Related Projects

Inspiration

rust-tools.nvim draws inspiration from akinsho/flutter-tools.nvim