rustaceanvim:为 Neovim 打造的 Rust 增强插件,集成 rust-analyzer 与调试、测试功能

🦀 Supercharge your Rust experience in Neovim! A heavily modified fork of rust-tools.nvim

分支4Tags253
文件最后提交记录最后更新时间
1 个月前
1 个月前
2 个月前
14 天前
9 个月前
6 个月前
4 个月前
2 年前
9 个月前
2 年前
9 个月前
10 个月前
9 个月前
2 年前
14 天前
2 年前
6 个月前
2 年前
1 个月前
2 天前
1 个月前
9 个月前
9 个月前
2 年前
9 个月前
2 年前

rustaceanvim


探索文档 »

报告 Bug · 请求功能 · 提出问题

增强你在 Neovim 中的 Rust 开发体验!
基于 rust-tools.nvim 深度修改的分支版本

🦀

Neovim Lua Rust Nix

GPL2 License Issues Build Status LuaRocks

Note

🔗 快速链接

❔ 我需要 rustaceanvim 吗

如果你刚开始接触 Rust,Neovim 内置的 LSP 客户端 API(参见 :h lsp)或 nvim-lspconfig.rust_analyzer 可能对你来说已经足够。它们提供了 LSP 支持的最基本功能。本插件适用于那些希望获得 特定于 rust-analyzer 的额外非标准功能 的用户。

📝 前置要求

必需条件

Note

如需与旧版 Neovim 兼容的版本, 请查看 更新日志 中的过往主要版本更新记录。

可选条件

📥 安装

打包状态

使用 Neovim 内置插件管理器

vim.pack.add {{
  src = 'https://github.com/mrcjkb/rustaceanvim',
  -- To avoid being surprised by breaking changes,
  -- I recommend you set a version range
  version = vim.version.range('^9')
}}

rocks.nvim

:Rocks install rustaceanvim

lazy.nvim

{
  'mrcjkb/rustaceanvim',
  -- To avoid being surprised by breaking changes,
  -- I recommend you set a version range
  version = '^9',
  -- This plugin implements proper lazy-loading (see :h lua-plugin-lazy).
  -- No need for lazy.nvim to lazy-load it.
  lazy = false,
}

Tip

如果你想避免出现破坏性变更,建议固定使用带标签的版本。

若要手动生成文档,请使用 :helptags ALL

Nix

对于启用了 flakes 的 Nix 用户,本项目以软件包和覆盖层的形式提供输出。 它也已收录于 nixpkgs 中。

请查看下方的配置信息以开始使用。

⚡ 快速设置

此插件会自动配置内置的 rust-analyzer LSP 客户端,并与其他 Rust 工具集成。 更多信息请参见使用 / 功能部分。

Warning

请勿调用 nvim-lspconfig.rust_analyzer 的 setup 函数,也不要手动为 rust-analyzer 设置 LSP 客户端, 否则可能会导致冲突。

这是一个开箱即用的文件类型插件,因此无需调用 setup 函数或进行任何配置即可使其正常工作。

你很可能需要添加一些键映射。大多数键映射仅在 Rust 文件中有用,因此建议你在 ~/.config/nvim/after/ftplugin/rust.lua[1] 中定义它们。

示例:

local bufnr = vim.api.nvim_get_current_buf()
vim.keymap.set(
  "n",
  "<leader>a",
  function()
    vim.cmd.RustLsp('codeAction') -- supports rust-analyzer's grouping
    -- or vim.lsp.buf.codeAction() if you don't want grouping.
  end,
  { silent = true, buffer = bufnr }
)
vim.keymap.set(
  "n",
  "K",  -- Override Neovim's built-in hover keymap with rustaceanvim's hover actions
  function()
    vim.cmd.RustLsp({'hover', 'actions'})
  end,
  { silent = true, buffer = bufnr }
)

Tip

  • 有关更多 LSP 相关的按键映射,请查看 nvim-lspconfig 的建议
  • 如果你想与 nvim-lspconfig 共享按键映射,也可以使用 vim.g.rustaceanvim.server.on_attach 函数,或者 LspAttach 自动命令。
  • 有关更多配置选项,请参见高级配置部分或 :h rustaceanvim.config

Important

  • 不要after/ftplugin/rust.lua 中设置 vim.g.rustaceanvim,因为该文件是在插件初始化之后才加载的。

📚 使用方法 / 功能特性

调试
  • debuggables 会打开一个提示,供你从可用目标中进行选择。
    • debug 会在当前光标位置搜索目标。
  :RustLsp[!] debuggables {args[]}?
  :RustLsp[!] debug {args[]}?
  vim.cmd.RustLsp('debug')
  vim.cmd.RustLsp('debuggables')
  -- or, to run the previous debuggable:
  vim.cmd.RustLsp { 'debuggables', bang = true }
  -- or, to override the executable's args:
  vim.cmd.RustLsp {'debuggables', 'arg1', 'arg2' }

使用 ! 调用命令将重新运行上一个可调试项。

要求:

默认情况下,当 LSP 客户端附加时,此插件会静默尝试自动加载 nvim-dap 配置。 加载完成后,你可以使用 require('dap').continue():DapContinue 调用它们。 通过设置 vim.g.rustaceanvim.dap.autoload_configurations = false 可以禁用此功能。

  • :RustLsp debuggables 只会加载由 rust-analyzer 创建的调试配置。
    • require('dap').continue() 会加载所有 Rust 调试配置,包括在 .vscode/launch.json 中指定的配置 (参见 :h dap-launch.json)。
    • 注意,rustaceanvim 可能只有在 rust-analyzer 完成初始化后(在大型项目中,这可能在客户端附加之后)才能加载 DAP 配置。 这意味着 DAP 配置可能不会在启动时立即加载。

可运行项
  • runnables 会打开一个提示,供你从可用目标中进行选择。
    • run 会在当前光标位置搜索目标。
  :RustLsp[!] runnables {args[]}?
  :RustLsp[!] run {args[]}?
  vim.cmd.RustLsp('run')
  vim.cmd.RustLsp('runnables')
  -- or, to run the previous runnable:
  vim.cmd.RustLsp { 'runnables', bang = true }
  -- or, to override the executable's args:
  vim.cmd.RustLsp {'runnables', 'arg1', 'arg2' }

使用感叹号 ! 调用命令将重新运行上次运行的可执行文件。

可测试项和失败测试诊断

如果将 vim.g.rustaceanvim.tools.test_executor 选项设置为 'background',此插件将在后台运行测试、解析结果,并在可能的情况下将失败的测试显示为诊断信息。

  :RustLsp[!] testables {args[]}?
  vim.cmd.RustLsp('testables')
  -- or, to run the previous testables:
  vim.cmd.RustLsp { 'testables', bang = true }
  -- or, to override the executable's args:
  vim.cmd.RustLsp {'testables', 'arg1', 'arg2' }

使用 ! 调用该命令将重新运行上次可测试项。

Neotest 集成

本插件提供了一个 neotest 适配器,你可以按以下方式将其添加到 neotest 中:

  require('neotest').setup {
      -- ...,
      adapters = {
        -- ...,
        require('rustaceanvim.neotest')
      },
  }

注意:如果您使用 rustaceanvim 的 neotest 适配器,请不要添加 neotest-rust

以下是 rustaceanvim 适配器与 neotest-rust 的对比:

rustaceanvim neotest-rust
测试发现 rust-analyzer (LSP) tree-sitter
命令构建 rust-analyzer (LSP) tree-sitter
DAP 策略 自动 DAP 检测(复用 debuggables);可通过 vim.g.rustaceanvim.dap 覆盖 默认使用 codelldb;需手动配置
测试运行器 cargocargo-nextest(若检测到) cargo-nextest

如果您将 rustaceanvim 配置为使用 neotest,tools.test_executor 将默认对 testables 和属于测试的 runnables 使用 neotest。

递归展开宏
  :RustLsp expandMacro {float?|horizontal?|vertical?}
  vim.cmd.RustLsp('expandMacro')
  vim.cmd.RustLsp({ 'expandMacro', 'float' })

未提供参数时,默认值为 vertical

Rebuild proc macros
  :RustLsp rebuildProcMacros
  vim.cmd.RustLsp('rebuildProcMacros')
上下移动项目
  :RustLsp moveItem {up|down}
  vim.cmd.RustLsp { 'moveItem',  'up' }
  vim.cmd.RustLsp { 'moveItem',  'down' }
分组代码操作

有时,rust-analyzer 会按类别对代码操作进行分组, 而 Neovim 的内置 vim.lsp.buf.codeAction 不支持这一功能。 本插件提供了一个带有 UI 的命令来实现此功能:

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

如果将选项 vim.g.rustaceanvim.tools.code_actions.ui_select_fallback 设置为 true(默认值为 false),那么当没有分组代码操作时,它将回退到 vim.ui.select

悬停操作

注意:要激活悬停操作,请运行该命令两次。这会将您移动到窗口中,然后按 Enter 选择您想要的选项。或者,您可以在配置中将 auto_focus 设置为 true,这样您将自动进入悬停操作窗口。

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

您可以通过切换到悬停窗口并在相应行上输入 <CR> 来调用悬停操作,或者使用 <Plug>RustHoverAction 映射的按键绑定,该映射接受 <count> 前缀作为要调用的悬停操作的(从 1 开始的)索引。

例如,如果您设置以下按键绑定:

 vim.keymap.set('n', '<space>a', '<Plug>RustHoverAction')

你可以使用 3<space>a 调用第三个悬停操作。

悬停范围
  :RustLsp hover range
  vim.cmd.RustLsp { 'hover', 'range' }
错误解释

在错误诊断上方显示悬浮窗口,其中包含来自 rust error codes index 的解释(如果存在错误代码)。

  :RustLsp explainError {cycle?|cycle_prev?|current?}
  vim.cmd.RustLsp('explainError') -- default to 'cycle'
  vim.cmd.RustLsp({ 'explainError', 'cycle' })
  vim.cmd.RustLsp({ 'explainError', 'cycle_prev' })
  vim.cmd.RustLsp({ 'explainError', 'current' })
  • 若使用 cycle 调用或不带参数调用: 类似 vim.diagnostic.goto_nextexplainError 会从光标位置开始循环遍历诊断信息, 直至找到包含错误代码的诊断。

    • 若使用 cycle_prev 调用: 类似 vim.diagnostic.goto_prev, 反向搜索包含错误代码的诊断信息。

    • 若使用 current 调用: 仅在当前光标所在行搜索诊断信息。

渲染诊断信息

显示一个悬浮窗口,其中包含渲染后的诊断信息,与 cargo build 过程中显示的格式一致。 对于解决涉及借用和泛型的 bug 非常有用, 因为它会将重要信息(有时跨文件)整合在一起。

  :RustLsp renderDiagnostic {cycle?|cycle_prev?|current?}
  vim.cmd.RustLsp('renderDiagnostic') -- defaults to 'cycle'
  vim.cmd.RustLsp({ 'renderDiagnostic', 'cycle' })
  vim.cmd.RustLsp({ 'renderDiagnostic', 'cycle_prev' })
  vim.cmd.RustLsp({ 'renderDiagnostic', 'current' })
  • 若使用 cycle 调用或不带参数调用: 类似 vim.diagnostic.goto_nextrenderDiagnostic 会从光标位置开始循环遍历诊断信息, 直至找到带有已渲染数据的诊断信息。

    • 若使用 cycle_prev 调用: 类似 vim.diagnostic.goto_prev, 反向搜索带有已渲染数据的诊断信息。

    • 若使用 current 调用: 仅在当前光标所在行搜索诊断信息。

跳转到相关诊断信息

有时,rust-analyzer 会在多个位置提供相关的诊断信息。 使用 relatedDiagnostics 子命令,您可以在这些诊断信息之间导航。 如果某个诊断信息包含多个相关诊断信息,此命令会将它们填充到 quickfix 列表中。

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

相关测试

查询 rust-analyzer 获取光标下符号(或其所属函数)的关联测试,并快速跳转到其中一个。

:RustLsp relatedTests
vim.cmd.RustLsp('relatedTests')
打开 Cargo.toml
  :RustLsp openCargo
  vim.cmd.RustLsp('openCargo')
打开 docs.rs 文档

打开光标下符号的 docs.rs 文档。

  :RustLsp openDocs
  vim.cmd.RustLsp('openDocs')
父模块
  :RustLsp parentModule
  vim.cmd.RustLsp('parentModule')
筛选工作区符号搜索

rust-analyzer 支持对工作区符号搜索进行筛选。

  :RustLsp[!] workspaceSymbol {onlyTypes?|allSymbols?} {query?}
  vim.cmd.RustLsp('workspaceSymbol')
  -- or
  vim.cmd.RustLsp {
    'workspaceSymbol',
    '<onlyTypes|allSymbols>' --[[ optional ]],
    '<query>' --[[ optional ]],
    bang = true --[[ optional ]]
  }
  • 使用感叹号 ! 调用命令将在搜索中包含依赖项。
Join lines

将选定行合并为一行,智能修复空白、尾随逗号和花括号。 在普通模式下适用于单行,在可视模式下适用于多行。

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

结构化搜索替换
  • 在普通模式下搜索整个缓冲区。
    • 在视觉模式下搜索所选内容。
  :RustLsp ssr {query}
  vim.cmd.RustLsp { 'ssr', '<query>' --[[ optional ]] }

tty

查看 crate 依赖图
  :RustLsp crateGraph {backend {output}}
  vim.cmd.RustLsp { 'crateGraph', '[backend]', '[output]' }

要求:

查看语法树

需要 rust-analyzer >= 2025-01-20。

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

rustaceanvim

快速检查

在后台线程中运行 cargo check 或其他兼容命令(例如 clippy),并根据命令输出提供 LSP 诊断信息。

这在大型项目中非常实用,因为在每次保存时运行 cargo check 可能会消耗较多资源。

  :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

只有当你将选项 ['rust-analyzer'].checkOnSave 设置为 false 时,此功能才有用。

查看 HIR / MIR

打开一个缓冲区,以文本形式展示光标所在函数的 HIR 或 MIR。 这在调试时或参与 rust-analyzer 自身开发时非常有用。

  :RustLsp view {hir|mir}
  vim.cmd.RustLsp { 'view', 'hir' }
  vim.cmd.RustLsp { 'view', 'mir' }
Rustc unpretty

打开一个缓冲区,以文本形式展示光标附近函数的 MIR 或其他内容,提供类似 Rust Playground 的体验。

注意:目前需要 Rust 的 tree-sitter 解析器和 nightly 编译器工具链。

  :Rustc unpretty {hir|mir|...}
  vim.cmd.Rustc { 'unpretty', 'hir' }
  vim.cmd.Rustc { 'unpretty', 'mir' }
  -- ...

要求:

  • Rust 的 tree-sitter 解析器(:Rustc unpretty 命令所需)。可使用 nvim-treesitter 进行安装。
lspmux

在 Linux 和 MacOS 上,rustaceanvim 能够自动检测并连接到正在运行的 lspmux 服务器。默认情况下,如果未设置 vim.g.rustaceanvim.server.cmd 选项,它将尝试自动执行此操作。另请参阅 :h rustaceanvim.lspmux

动态配置 rust-analyzer

您可以使用 :RustAnalyzer config 子命令动态配置 rust-analyzer。该命令接受一个 Lua 表作为参数(不会对其进行验证!)。

例如:

  :RustAnalyzer config { checkOnSave = false }
  vim.cmd.RustAnalyzer { 'config', '{ checkOnSave = false }' }

另请参阅:rust-analyzer 配置

⚙️ 高级配置

若要修改默认配置,请设置 vim.g.rustaceanvim

你只需指定想要更改的键,因为未提供的键将应用默认值。

示例配置:

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

Tip

  • vim.g.rustaceanvim 也可以是一个返回表的函数。

  • 你也可以使用 :h vim.lsp.config 来配置 vim.g.rustaceanvim.server 选项。 例如,vim.lsp.config("*", {})vim.lsp.config("rust-analyzer", {})

使用 codelldb 进行调试

对于 Rust 而言,CodeLLDB VSCode 扩展 中的 codelldb 提供了比 lldb 更好的体验。 如果你使用的发行版允许你安装 codelldb 可执行文件,此插件会自动检测到它并将自身配置为使用其作为调试适配器。

一些示例:

如果你的发行版没有 codelldb 包,你可以按以下步骤配置:

  1. 安装 CodeLLDB VSCode 扩展
  2. 找出其安装位置。在 Linux 上,通常位于 $HOME/.vscode/extensions/
  3. 更新你的配置:
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

如何为不同项目动态加载不同的 rust-analyzer 设置

你可以使用 codesettings.nvim, 它支持从 .vscode/settings.json[2] 等文件加载项目本地的 LSP 设置。 如果安装了该插件,rustaceanvim 会尝试自动调用它。

另一个选项是使用 :h exrc

🩺 故障排除

健康检查

要进行健康检查,请运行 :checkhealth rustaceanvim

rust-analyzer 日志文件

要打开 rust-analyzer 日志文件,请运行 :RustLsp logFile

最小配置

要在临时目录中使用最小配置来排查此插件问题, 你可以尝试 minimal.lua

nvim -u minimal.lua

Important

我强烈建议不要使用由 mason.nvim 管理的 rust-analyzer,因为 rust-analyzer 与项目工具链之间的版本不匹配可能会(而且很可能会)导致一些难以察觉的问题。

如果您无法使用最小化配置复现问题,那么问题可能是由其他插件或插件管理器的设置引起的。在这种情况下,请将其他插件和配置添加到 minimal.lua 中,直到能够复现问题。或者,对现有的插件和配置进行二分排查。

Note

如果您使用 Nix,可以运行 nix run "github:mrcjkb/rustaceanvim#nvim-minimal-stable"。 或者 nix run "github:mrcjkb/rustaceanvim#nvim-minimal-nightly"

rust-analyzer 故障排除

对于与 rust-analyzer 相关的问题(例如 LSP 功能无法正常工作),另请参阅 rust-analyzer 故障排除指南

🗨️ 常见问题解答

嵌入提示(inlay hints)/ 类型提示在哪里?

由于 Neovim >= 0.10 原生支持嵌入提示,我已从本插件中移除了相关代码。请参阅 :h lsp-inlay_hint

能否将嵌入提示显示到行尾?

您可以使用 nvim-lsp-endhints 插件。

如何启用自动补全?

#ff097f2091e7a970e5b12960683b4dade5563040 开始,Neovim 已具备基于语言服务器发送的 triggerCharacters 的内置补全功能。全能补全(Omni completion)也可用于提供更传统的 vim 式补全体验。

对于更具可扩展性和复杂性的自动补全设置,您需要一个插件,例如 nvim-cmp 以及一个 LSP 补全源,如 cmp-nvim-lsp,或者您也可以使用 blink.cmp

我在(自动)补全方面遇到问题

rustaceanvim 不实现(自动)补全功能。(自动)补全方面的问题要么来自其他插件,要么来自 rust-analyzer。

mason.nvim 和 nvim-lspconfig

有关 mason.nvim 和 nvim-lspconfig 问题的故障排除,或配置 rustaceanvim 以使用由 mason.nvim 管理的 rust-analyzer 安装的详细信息,请参阅 :h rustaceanvim.mason

我在单个独立文件中看不到诊断信息

rust-analyzer 对独立文件的支持有限。许多诊断信息来自 Cargo。如果您不在 Cargo 项目中,将不会看到任何 Cargo 诊断信息。

可调试目标未添加到 nvim-dap

因为 rustaceanvim 会在 LSP 客户端附加时自动添加目标,为避免向您发送过多通知,它会静默失败。要排查可调试目标问题,请使用 :RustLsp debuggables

🔗 相关项目

灵感来源

rust-tools.nvim 的灵感来源于 akinsho/flutter-tools.nvim


  1. 参见 :help base-directories ↩︎

  2. 参见 此示例 和 rust-analyzer 配置手册↩︎

项目介绍

在Neovim中全面提升您的Rust编程体验!这是一个对rust-tools.nvim进行大量改进的分支版本。【此简介由AI生成】

定制我的领域
73.11 K135访问 GitHub