rust better

This commit is contained in:
RingOfStorms (Joshua Bell) 2023-07-16 19:38:55 -05:00
parent 8ce76c7c91
commit f059534f62
4 changed files with 323 additions and 270 deletions

View file

@ -1,228 +1,249 @@
function prereqs()
local output = vim.fn.system({
"which",
"rust-analyzer",
"&&",
"rust-analyzer",
"--version",
})
if output == nil or output == "" or string.find(output, "not installed for the toolchain") then
print("Installing rust-analyzer globally with rustup")
vim.fn.system({
"rustup", "component", "add", "rust-analyzer"
})
end
end
local servers = { local servers = {
rust_analyzer = { -- rust_analyzer = USES RUST_TOOLS INSTEAD, SEE BOTTOM OF THIS FILE
-- rust tsserver = {
-- to enable rust-analyzer settings visit: -- typescript/javascript
-- https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/generated_config.adoc },
["rust-analyzer"] = { pyright = {
cargo = { -- python
allFeatures = true, },
}, lua_ls = {
checkOnSave = { -- lua
allFeatures = true, Lua = {
command = "clippy", workspace = { checkThirdParty = false },
}, telemetry = { enable = false },
}, },
}, },
tsserver = { bashls = {
-- typescript/javascript -- bash
}, },
pyright = { cssls = {
-- python -- css
}, },
lua_ls = { cssmodules_ls = {
-- lua -- css modules
Lua = { },
workspace = { checkThirdParty = false }, dockerls = {
telemetry = { enable = false }, -- docker
}, },
}, docker_compose_language_service = {
bashls = { -- docker compose
-- bash },
}, jsonls = {
cssls = { -- json
-- css },
}, marksman = {
cssmodules_ls = { -- markdown
-- css modules },
}, taplo = {
dockerls = { -- toml
-- docker },
}, yamlls = {
docker_compose_language_service = { -- yaml
-- docker compose },
}, lemminx = {
jsonls = { -- xml
-- json },
}, rnix = {
marksman = { -- Nix
-- markdown },
}, ansiblels = {
taplo = { -- ansible
-- toml },
},
yamlls = {
-- yaml
},
lemminx = {
-- xml
},
rnix = {
-- Nix
},
ansiblels = {
-- ansible
},
} }
-- LSP config -- LSP config
-- Took lots of inspiration from this kickstart lua file: https://github.com/hjr3/dotfiles/blob/main/.config/nvim/init.lua -- Took lots of inspiration from this kickstart lua file: https://github.com/hjr3/dotfiles/blob/main/.config/nvim/init.lua
-- This function gets run when an LSP connects to a particular buffer.
local on_attach = function(client, bufnr)
local nmap = function(keys, func, desc)
if desc then
desc = "LSP: " .. desc
end
vim.keymap.set("n", keys, func, { buffer = bufnr, desc = desc })
end
nmap("<leader>lr", vim.lsp.buf.rename, "[R]ename")
nmap("<leader>la", vim.lsp.buf.code_action, "Code [A]ction")
nmap("gd", vim.lsp.buf.definition, "[G]oto [D]efinition")
nmap("gr", require("telescope.builtin").lsp_references, "[G]oto [R]eferences")
nmap("gI", vim.lsp.buf.implementation, "[G]oto [I]mplementation")
nmap("<leader>D", vim.lsp.buf.type_definition, "Type [D]efinition")
-- See `:help K` for why this keymap
nmap("K", vim.lsp.buf.hover, "Hover Documentation")
nmap("<C-k>", vim.lsp.buf.signature_help, "Signature Documentation")
-- Lesser used LSP functionality
nmap("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration")
-- disable tsserver so it does not conflict with prettier
if client.name == "tsserver" then
client.server_capabilities.document_formatting = false
end
end
return { return {
{ {
-- Autocompletion "lvimuser/lsp-inlayhints.nvim",
"hrsh7th/nvim-cmp", },
dependencies = { {
"hrsh7th/cmp-nvim-lsp", -- Autocompletion
"L3MON4D3/LuaSnip", "hrsh7th/nvim-cmp",
"saadparwaiz1/cmp_luasnip", dependencies = {
"hrsh7th/cmp-buffer", "hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-path", "L3MON4D3/LuaSnip",
}, "saadparwaiz1/cmp_luasnip",
}, "hrsh7th/cmp-buffer",
{ "hrsh7th/cmp-path",
"williamboman/mason.nvim", --"Saecki/crates.nvim", -- SEE plugins/rust-tools.lua
cmd = { },
"Mason", },
"MasonUpdate", {
"MasonInstall", "williamboman/mason.nvim",
"MasonInstallAll", cmd = {
"MasonUninstall", "Mason",
"MasonUninstallAll", "MasonUpdate",
"MasonLog", "MasonInstall",
}, "MasonInstallAll",
build = ":MasonUpdate", "MasonUninstall",
opts = {}, "MasonUninstallAll",
}, "MasonLog",
{ },
"williamboman/mason-lspconfig.nvim", build = ":MasonUpdate",
}, opts = {},
{ "folke/neodev.nvim", opts = {} }, },
{ {
"neovim/nvim-lspconfig", "williamboman/mason-lspconfig.nvim",
dependencies = { "nvim-telescope/telescope.nvim" }, },
config = function() {
local config = require("lspconfig") "neovim/nvim-lspconfig",
local util = require("lspconfig/util") dependencies = { "nvim-telescope/telescope.nvim" },
local mason_lspconfig = require("mason-lspconfig") config = function()
local cmp = require("cmp") local config = require("lspconfig")
local luasnip = require("luasnip") local util = require("lspconfig/util")
local mason_lspconfig = require("mason-lspconfig")
local cmp = require("cmp")
local luasnip = require("luasnip")
-- LSP -- LSP
-- This function gets run when an LSP connects to a particular buffer. -- nvim-cmp supports additional completion capabilities, so broadcast that to servers
local on_attach = function(client, bufnr) local capabilities = vim.lsp.protocol.make_client_capabilities()
local nmap = function(keys, func, desc) capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities)
if desc then
desc = "LSP: " .. desc
end
vim.keymap.set("n", keys, func, { buffer = bufnr, desc = desc }) -- Install servers used
end mason_lspconfig.setup({
ensure_installed = vim.tbl_keys(servers),
})
nmap("<leader>lr", vim.lsp.buf.rename, "[R]ename") local flags = {
nmap("<leader>la", vim.lsp.buf.code_action, "Code [A]ction") allow_incremental_sync = true,
debounce_text_changes = 200,
}
nmap("gd", vim.lsp.buf.definition, "[G]oto [D]efinition") mason_lspconfig.setup_handlers({
nmap("gr", require("telescope.builtin").lsp_references, "[G]oto [R]eferences") function(server_name)
nmap("gI", vim.lsp.buf.implementation, "[G]oto [I]mplementation") config[server_name].setup({
nmap("<leader>D", vim.lsp.buf.type_definition, "Type [D]efinition") flags = flags,
capabilities = capabilities,
on_attach = on_attach,
settings = servers[server_name],
})
end,
})
-- See `:help K` for why this keymap -- Completion
nmap("K", vim.lsp.buf.hover, "Hover Documentation") luasnip.config.setup({})
nmap("<C-k>", vim.lsp.buf.signature_help, "Signature Documentation")
-- Lesser used LSP functionality cmp.setup({
nmap("gD", vim.lsp.buf.declaration, "[G]oto [D]eclaration") snippet = {
expand = function(args)
-- disable tsserver so it does not conflict with prettier luasnip.lsp_expand(args.body)
if client.name == "tsserver" then end,
client.server_capabilities.document_formatting = false },
end mapping = cmp.mapping.preset.insert({
end ["<C-n>"] = cmp.mapping.select_next_item(),
["<C-p>"] = cmp.mapping.select_prev_item(),
-- nvim-cmp supports additional completion capabilities, so broadcast that to servers ["<C-d>"] = cmp.mapping.scroll_docs(-4),
local capabilities = vim.lsp.protocol.make_client_capabilities() ["<C-f>"] = cmp.mapping.scroll_docs(4),
capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities) ["<C-Space>"] = cmp.mapping.complete({}),
["<CR>"] = cmp.mapping.confirm({
-- Install servers used behavior = cmp.ConfirmBehavior.Replace,
mason_lspconfig.setup({ select = true,
ensure_installed = vim.tbl_keys(servers), }),
}) ["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
local flags = { cmp.select_next_item()
allow_incremental_sync = true, elseif luasnip.expand_or_jumpable() then
debounce_text_changes = 200, luasnip.expand_or_jump()
} else
fallback()
mason_lspconfig.setup_handlers({ end
function(server_name) end, { "i", "s" }),
require("lspconfig")[server_name].setup({ ["<S-Tab>"] = cmp.mapping(function(fallback)
flags = flags, if cmp.visible() then
capabilities = capabilities, cmp.select_prev_item()
on_attach = on_attach, elseif luasnip.jumpable(-1) then
settings = servers[server_name], luasnip.jump(-1)
}) else
end, fallback()
}) end
end, { "i", "s" }),
-- Completion }),
luasnip.config.setup({}) sources = {
{ name = "nvim_lsp", priority = 8 },
cmp.setup({ { nane = "buffer", priority = 7 },
snippet = { { name = "luasnip", priority = 6 },
expand = function(args) { name = "path" },
luasnip.lsp_expand(args.body) { name = "crates" },
end, },
}, sorting = {
mapping = cmp.mapping.preset.insert({ priority_weight = 1,
["<C-n>"] = cmp.mapping.select_next_item(), comparators = {
["<C-p>"] = cmp.mapping.select_prev_item(), cmp.config.compare.locality,
["<C-d>"] = cmp.mapping.scroll_docs(-4), cmp.config.compare.recently_used,
["<C-f>"] = cmp.mapping.scroll_docs(4), cmp.config.compare.score,
["<C-Space>"] = cmp.mapping.complete({}), cmp.config.compare.offset,
["<CR>"] = cmp.mapping.confirm({ cmp.config.compare.order,
behavior = cmp.ConfirmBehavior.Replace, },
select = true, },
}), window = {
["<Tab>"] = cmp.mapping(function(fallback) completion = cmp.config.window.bordered(),
if cmp.visible() then documentation = cmp.config.window.bordered(),
cmp.select_next_item() },
elseif luasnip.expand_or_jumpable() then })
luasnip.expand_or_jump() end,
else },
fallback() { "folke/neodev.nvim", opts = {} }, -- lua stuff
end { -- Rust tools
end, { "i", "s" }), "simrat39/rust-tools.nvim",
["<S-Tab>"] = cmp.mapping(function(fallback) build = prereqs,
if cmp.visible() then opts = {
cmp.select_prev_item() server = {
elseif luasnip.jumpable(-1) then on_attach = on_attach
luasnip.jump(-1) },
else },
fallback() --config = function(_, opts)
end --require('rust-tools').setup(opts)
end, { "i", "s" }), --end
}), },
sources = { { "Saecki/crates.nvim", tag = "v0.3.0", dependencies = { "nvim-lua/plenary.nvim" }, opts = {} },
{ name = "nvim_lsp", priority = 8 },
{ nane = "buffer", priority = 7 },
{ name = "luasnip", priority = 6 },
{ name = "path" },
},
sorting = {
priority_weight = 1,
comparators = {
cmp.config.compare.locality,
cmp.config.compare.recently_used,
cmp.config.compare.score,
cmp.config.compare.offset,
cmp.config.compare.order,
},
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
})
end,
},
} }

View file

@ -1,60 +1,88 @@
function prereqs() function prereqs()
local output = vim.fn.system({ local output = vim.fn.system({
"which", "which",
"cspell", "cspell",
}) })
if output == nil or output == "" then if output == nil or output == "" then
print("Installing cspell globally with npm") print("Installing cspell globally with npm")
vim.fn.system({ vim.fn.system({
"npm", "npm",
"install", "install",
"-g", "-g",
"cspell@latest", "cspell@latest",
}) })
end end
end end
return { return {
{ {
"jose-elias-alvarez/null-ls.nvim", "jose-elias-alvarez/null-ls.nvim",
dependencies = { "williamboman/mason.nvim" }, dependencies = { "williamboman/mason.nvim" },
build = prereqs, build = prereqs,
opts = function(_, config) opts = function(_, config)
-- config variable is the default definitions table for the setup function call -- config variable is the default definitions table for the setup function call
local null_ls = require("null-ls") local null_ls = require("null-ls")
-- Check supported formatters and linters -- Custom rust formatter: genemichaels first, then rustfmt, nightly if experimental
-- https://github.com/jose-elias-alvarez/null-ls.nvim/tree/main/lua/null-ls/builtins/formatting local rust_formatter_genemichaels = {
-- https://github.com/jose-elias-alvarez/null-ls.nvim/tree/main/lua/null-ls/builtins/diagnostics name = "rust_formatter_genemichaels",
config.sources = { method = null_ls.methods.FORMATTING,
-- Set a formatter filetypes = { "rust" },
null_ls.builtins.formatting.prettier, -- typescript/javascript generator = null_ls.formatter({
null_ls.builtins.formatting.stylua, command = "genemichaels",
null_ls.builtins.formatting.rustfmt, args = { '-q' },
null_ls.builtins.formatting.black, -- python to_stdin = true,
-- null_ls.builtins.code_actions.proselint, -- TODO looks interesting }),
null_ls.builtins.code_actions.cspell.with({ }
config = { -- ╰─ cat src/main.rs| rustfmt --emit=stdout --edition=2021 --color=never
find_json = function() local rust_formatter_rustfmt = {
return vim.fn.findfile("cspell.json", vim.fn.environ().HOME .. "/.config/nvim/lua/user/;") name = "rust_formatter_rustfmt",
end, method = null_ls.methods.FORMATTING,
}, filetypes = { "rust" },
}), generator = null_ls.formatter({
null_ls.builtins.diagnostics.cspell.with({ command = "rustfmt",
extra_args = { "--config", "~/.config/nvim/lua/user/cspell.json" }, args = { '--emit=stdout', "--edition=$(grep edition Cargo.toml | awk '{print substr($3,2,length($3)-2)}')",
}), '--color=never' },
} to_stdin = true,
}),
}
config.update_in_insert = true null_ls.register(rust_formatter_genemichaels)
config.debug = true null_ls.register(rust_formatter_rustfmt)
return config -- Check supported formatters and linters
end, -- https://github.com/jose-elias-alvarez/null-ls.nvim/tree/main/lua/null-ls/builtins/formatting
}, -- https://github.com/jose-elias-alvarez/null-ls.nvim/tree/main/lua/null-ls/builtins/diagnostics
{ config.sources = {
"jay-babu/mason-null-ls.nvim", null_ls.builtins.formatting.prettier, -- typescript/javascript
opts = { null_ls.builtins.formatting.stylua, -- lua
ensure_installed = { "rustfmt", "stylelua", "prettier", "black" }, --null_ls.builtins.formatting.rustfmt, -- rust
}, rust_formatter_genemichaels, -- order matters, we run genemichaels first then rustfmt
}, rust_formatter_rustfmt,
null_ls.builtins.formatting.black, -- python
-- null_ls.builtins.code_actions.proselint, -- TODO looks interesting
null_ls.builtins.code_actions.cspell.with({
config = {
find_json = function()
return vim.fn.findfile("cspell.json", vim.fn.environ().HOME .. "/.config/nvim/lua/user/;")
end,
},
}),
null_ls.builtins.diagnostics.cspell.with({
extra_args = { "--config", "~/.config/nvim/lua/user/cspell.json" },
}),
}
config.update_in_insert = true
config.debug = true
return config
end,
},
{
"jay-babu/mason-null-ls.nvim",
opts = {
ensure_installed = { "rustfmt", "stylelua", "prettier", "black" },
},
},
} }

View file

@ -1,5 +0,0 @@
return {
"simrat39/rust-tools.nvim",
event = "BufEnter *.rs",
dependencies = { "mason-lspconfig.nvim", "lvimuser/lsp-inlayhints.nvim" },
}

View file

@ -0,0 +1,9 @@
return {
{
"simrat39/rust-tools.nvim",
event = "BufEnter *.rs",
dependencies = { "mason-lspconfig.nvim", "lvimuser/lsp-inlayhints.nvim" },
opts = {},
},
{ "Saecki/crates.nvim", tag = "v0.3.0", dependencies = { "nvim-lua/plenary.nvim" }, opts = {} },
}