Вопрос или проблема
Как мне настроить конфигурацию lsp в neovim для форматирования моего кода на Rust в желаемом стиле? Как заставить его следовать тому, что указано в ~/.config/rustfmt/rustfmt.toml
? Мой глобальный rustfmt.toml неверен или моя конфигурация LSP не использует его так, как должна?
У меня установлена последняя версия rust-analyzer с Mason.
Вот мой none-ls.lua
:
return {
"nvimtools/none-ls.nvim",
config = function()
local null_ls = require("null-ls")
local eslint_d_path = vim.fn.stdpath("data") .. "/mason/bin/eslint_d"
null_ls.setup({
sources = {
null_ls.builtins.formatting.stylua,
null_ls.builtins.formatting.prettier,
null_ls.builtins.diagnostics.eslint_d.with({
command = eslint_d_path,
extra_args = { "--config", vim.fn.expand(vim.loop.cwd() .. "/eslint.config.mjs") },
condition = function(utils)
return utils.root_has_file("eslint.config.mjs")
end,
}),
null_ls.builtins.formatting.shfmt,
},
})
vim.keymap.set("n", "gf", vim.lsp.buf.format, {})
end,
}
Мне нравится этот стиль форматирования:
pub fn run(address: &str) -> Result<Server, std::io::Error> {
let server = HttpServer::new(|| {
App::new()
.route("/health_check", web::get().to(health_check))
})
.bind(address)?
.run();
Ok(server)
}
но в моем буфере vim, если я нажимаю
(то есть vim.keymap.set("n", "
, определенный в none-ls.lua
). Он переформатируется в:
pub fn run(address: &str) -> Result<Server, std::io::Error> {
let server = HttpServer::new(|| App::new().route("/health_check", web::get().to(health_check)))
.bind(address)?
.run();
Ok(server)
}
в lsp-config.lua
(я добавлю весь файл внизу тоже):
lspconfig.rust_analyzer.setup({
capabilities = capabilities,
settings = {
["rust-analyzer"] = {
cargo = {
allFeatures = true,
features = { "ssr" },
},
procMacro = {
ignored = {
leptos_macro = {
-- "component", -- Раскомментируйте, если нужно
"server",
},
},
},
rustfmt = {
overrideCommand = { "rustfmt", "--edition", "2018" },
config = "~/.config/rustfmt/rustfmt.toml",
},
},
},
})
и у меня есть ~/.config/rustfmt/rustfmt.toml
:
[general]
# Убедитесь, что функции форматируются с новой строкой перед открывающей фигурной скобкой
fn_brace_style = "SameLineWhere"
[style]
# Используйте компактный стиль для замыканий
fn_call_style = "Visual"
lsp-config.lua
return {
{
"williamboman/mason.nvim",
lazy = false,
config = function()
require("mason").setup()
end,
},
{
"williamboman/mason-lspconfig.nvim",
lazy = false,
opts = {
auto_install = true,
},
},
{
"neovim/nvim-lspconfig",
lazy = false,
config = function()
local capabilities = require("cmp_nvim_lsp").default_capabilities()
local lspconfig = require("lspconfig")
-- Убедитесь, что ESLint настроен
lspconfig.eslint.setup({
capabilities = capabilities,
root_dir = lspconfig.util.root_pattern(
".eslintrc",
".eslintrc.js",
".eslintrc.json",
".eslintrc.yaml",
"eslint.config.mjs",
".git"
),
settings = {
workingDirectory = { mode = "auto" },
},
})
lspconfig.tsserver.setup({
capabilities = capabilities,
})
lspconfig.html.setup({
capabilities = capabilities,
})
lspconfig.lua_ls.setup({
capabilities = capabilities,
})
lspconfig.rust_analyzer.setup({
capabilities = capabilities,
settings = {
["rust-analyzer"] = {
cargo = {
allFeatures = true,
features = { "ssr" },
},
procMacro = {
ignored = {
leptos_macro = {
-- "component", -- Раскомментируйте, если нужно
"server",
},
},
},
rustfmt = {
overrideCommand = { "rustfmt", "--edition", "2018" },
config = "~/.config/rustfmt/rustfmt.toml",
},
},
},
})
lspconfig.sqlls.setup({
root_dir = function(fname)
return vim.fn.getcwd()
end,
capabilities = capabilities,
})
lspconfig.taplo.setup({
capabilities = capabilities,
})
lspconfig.emmet_language_server.setup({
capabilities = capabilities,
filetypes = {
"html",
"css",
"javascriptreact",
"typescriptreact",
"javascript",
"typescript",
"jsx",
"tsx",
},
})
-- lspconfig.prisma_language_server.setup({
-- capabilities = capabilities,
-- })
vim.keymap.set("n", "K", vim.lsp.buf.hover, {})
vim.keymap.set("n", "e", vim.diagnostic.open_float)
vim.keymap.set("n", "E", vim.diagnostic.setloclist)
vim.keymap.set("n", "gd", vim.lsp.buf.definition, {})
vim.keymap.set("n", "gr", vim.lsp.buf.references, {})
-- vim.keymap.set("n", "ca", vim.lsp.buf.code_action, {})
-- vim.keymap.set("v", "ca", vim.lsp.buf.code_action, {})
vim.keymap.set({ "n", "v" }, "ca", vim.lsp.buf.code_action, {})
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev)
vim.keymap.set("n", "]d", vim.diagnostic.goto_next)
end,
},
}
Ответ или решение
Настройка формата кода Rust в Neovim с использованием rust-analyzer и rustfmt
Если вы хотите отформатировать ваш код на Rust в соответствии с установленным стилем, указанным в файле ~/.config/rustfmt/rustfmt.toml
, вам нужно убедиться, что ваша LSP (Language Server Protocol) конфигурация правильно настроена для использования rustfmt и что ваши настройки корректны. Давайте разберем необходимые шаги для решения этой проблемы.
Шаг 1: Проверка конфигурации rustfmt
Сначала убедитесь, что ваш файл конфигурации Rustfmt (~/.config/rustfmt/rustfmt.toml
) корректен. Ваш текущий файл имеет следующий вид:
[general]
# Ensure that functions are formatted with a newline before the opening brace
fn_brace_style = "SameLineWhere"
[style]
# Use a compact style for closures
fn_call_style = "Visual"
В целом, настройки выглядят приемлемо. Однако вы можете проверить актуальность выбранных параметров через документацию Rustfmt, чтобы увидеть, подходят ли они под ваши критерии форматирования.
Шаг 2: Настройка rust-analyzer
В вашей конфигурации LSP rust-analyzer убедитесь, что параметр для конфигурации rustfmt правильно настроен. Ваш текущий код выглядит следующим образом:
lspconfig.rust_analyzer.setup({
capabilities = capabilities,
settings = {
["rust-analyzer"] = {
cargo = {
allFeatures = true,
features = { "ssr" },
},
rustfmt = {
overrideCommand = { "rustfmt", "--edition", "2018" },
config = "~/.config/rustfmt/rustfmt.toml",
},
},
},
})
Основные аспекты тут:
- Ви можете попробовать изменить
overrideCommand
на{"rustfmt", "--config-path", "~/.config/rustfmt/rustfmt.toml"}
для явной передачи пути к конфигу, если это требуется. - Убедитесь, что путь указан правильно, а rustfmt действительно использует этот файл.
Шаг 3: Проверка интеграции с null-ls
Код в вашем none-ls.lua
указывает, что вы используете null-ls
вместе с rust-analyzer для форматирования:
null_ls.setup({
sources = {
-- ...
null_ls.builtins.formatting.shfmt,
},
})
Если вы хотите, чтобы rustfmt использовался вместе с null-ls, добавьте следующий источник перед другими элементами в sources
:
null_ls.builtins.formatting.rustfmt.with({
extra_args = { "--config-path", "~/.config/rustfmt/rustfmt.toml" }
}),
Шаг 4: Отладка
-
Проверка консоли: Включите отладку для rust-analyzer, чтобы увидеть, какие конфигурации он использует и какие ошибки могут возникать.
-
Команда формата: Запустите команду форматирования напрямую из вашего терминала, чтобы убедиться, что rustfmt применяет ваши настройки. Попробуйте:
rustfmt --config-path ~/.config/rustfmt/rustfmt.toml path/to/your/file.rs
-
Убедитесь: Если после всех настроек и тестов проблема сохраняется, убедитесь, что у вас актуальная версия rust-analyzer и rustfmt.
Заключение
Правильно настроенная конфигурация LSP и rustfmt позволит вам пользоваться желаемым стилем форматирования в Neovim. Следуйте предложенным шагам, чтобы устранить возможные недоработки и интегрировать форматирование по вашим предпочтениям.