dotfiles/nvim/.config/nvim/lua/plugins/ide.lua

372 lines
8.7 KiB
Lua

local linters = {
astro = { "eslint_d" },
bash = { "shellcheck" },
javascript = { "eslint_d" },
javascriptreact = { "eslint_d" },
markdown = { "markdownlint", "vale" },
quarto = { "markdownlint", "vale" },
sh = { "shellcheck" },
svelte = { "eslint_d" },
text = { "vale" },
typescript = { "eslint_d" },
typescriptreact = { "eslint_d" },
}
local formatters = {
angular = { { "prettierd", "prettier" } },
astro = { { "prettierd", "prettier" } },
bash = { "shfmt" },
bib = { "bibtex-tidy" },
css = { { "prettierd", "prettier" } },
graphql = { { "prettierd", "prettier" } },
html = { { "prettierd", "prettier" } },
javascript = { { "prettierd", "prettier" } },
javascriptreact = { { "prettierd", "prettier" } },
json = { "jq" },
lua = { "stylua" },
python = { "ruff_fix", "ruff_format" },
sh = { "shfmt" },
svelte = { { "prettierd", "prettier" } },
typescript = { { "prettierd", "prettier" } },
typescriptreact = { { "prettierd", "prettier" } },
vue = { { "prettierd", "prettier" } },
yaml = { { "prettierd", "prettier" } },
zsh = { "shfmt" },
}
return {
-- vista-like outline view for code
{
"stevearc/aerial.nvim",
config = true,
-- Optional dependencies
dependencies = {
"nvim-treesitter/nvim-treesitter",
"nvim-tree/nvim-web-devicons",
},
cmd = {
"AerialToggle",
"AerialOpen",
"AerialOpenAll",
"AerialClose",
"AerialCloseAll",
"AerialNext",
"AerialPrev",
"AerialGo",
"AerialInfo",
"AerialNavToggle",
"AerialNavOpen",
"AerialNavClose",
},
opts = {
backends = { "treesitter", "lsp", "markdown", "man" },
},
keys = {
{ "<leader>so", "<cmd>AerialNavToggle<cr>", silent = true, desc = "symbol navigator" },
{ "<leader>sO", "<cmd>AerialToggle<cr>", silent = true, desc = "symbol outline" },
},
},
-- lsp setup
{
"junnplus/lsp-setup.nvim",
dependencies = {
{
"neovim/nvim-lspconfig",
-- will sometimes not keep up with lsp changes if set to stable
version = false,
},
{
"williamboman/mason.nvim",
cmd = {
"Mason",
"MasonInstall",
"MasonUninstall",
"MasonUninstallAll",
"MasonLog",
"MasonUpdate",
},
build = ":MasonUpdate",
keys = {
{ "<leader>vm", ":Mason<cr>", desc = "Mason" },
},
},
{
"williamboman/mason-lspconfig.nvim",
cmd = { "LspInstall", "LspUninstall" },
},
{ "WhoIsSethDaniel/mason-tool-installer.nvim" },
},
event = { "BufRead", "BufNewFile", "InsertEnter" },
after = { "nvim-cmp" },
config = function()
require("plugins.config.lsp")
end,
keys = { { "<leader>vs", ":LspInfo<cr>", desc = "LspInfo" } },
},
-- very very pretty lsp 'peek' menus
{
"DNLHC/glance.nvim",
opts = { border = { enable = true }, theme = { enable = true, mode = "auto" } },
cmd = { "Glance" },
},
-- linting setup
{
"mfussenegger/nvim-lint",
config = function()
require("lint").linters_by_ft = linters
vim.api.nvim_create_autocmd({ "BufWritePost", "InsertLeave" }, {
callback = function()
if not vim.g.disable_autolint then
require("lint").try_lint()
end
end,
})
end,
event = { "BufWritePost", "InsertLeave" },
},
-- formatting setup
{
"stevearc/conform.nvim",
config = function()
require("conform").setup({
lsp_fallback = true,
format_after_save = function(bufnr)
if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then
return
end
return { lsp_fallback = true }
end,
formatters_by_ft = formatters,
formatters = {
-- enable python isort functionality
ruff_fix = {
prepend_args = { "--select", "I" },
},
},
})
vim.api.nvim_create_user_command("FormatDisable", function(args)
if args.bang then
-- FormatDisable! will disable formatting just for this buffer
vim.b.disable_autoformat = true
else
vim.g.disable_autoformat = true
end
end, {
desc = "Disable formatting on save",
bang = true,
})
vim.api.nvim_create_user_command("FormatEnable", function()
vim.b.disable_autoformat = false
vim.g.disable_autoformat = false
end, {
desc = "Enable formatting on save",
})
end,
cmd = { "ConformInfo" },
event = { "BufReadPre" },
keys = {
{
"<localleader>ll",
function()
require("conform").format({ async = true, lsp_fallback = true })
end,
desc = "Format buffer",
},
{
"<localleader>lL",
function()
vim.g.disable_autoformat = not vim.g.disable_autoformat
end,
desc = "Toggle AutoFormat",
},
{
"<leader>vf",
":ConformInfo<cr>",
desc = "ConformInfo",
},
},
init = function()
-- If you want the formatexpr, here is the place to set it
vim.o.formatexpr = "v:lua.require'conform'.formatexpr()"
end,
},
-- completion setup
{
"hrsh7th/nvim-cmp",
branch = "main",
dependencies = {
"andersevenrud/cmp-tmux",
"cbarrete/completion-vcard",
"f3fora/cmp-spell",
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-path",
"hrsh7th/cmp-buffer",
"hrsh7th/cmp-calc",
"hrsh7th/cmp-cmdline",
"hrsh7th/cmp-nvim-lua",
"hrsh7th/cmp-nvim-lsp-signature-help",
"dmitmel/cmp-digraphs",
"jc-doyle/cmp-pandoc-references",
"kdheepak/cmp-latex-symbols",
"lukas-reineke/cmp-rg",
"crispgm/cmp-beancount",
"ray-x/cmp-treesitter",
"saadparwaiz1/cmp_luasnip",
{
"L3MON4D3/LuaSnip",
dependencies = { "rafamadriz/friendly-snippets" },
},
},
config = function()
require("plugins.config.cmp")
end,
event = { "InsertEnter", "CmdlineEnter" },
},
-- useful quickfix-like buffer
{
"folke/trouble.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
opts = {},
cmd = {
"Trouble",
"TroubleRefresh",
"TroubleToggle",
"TroubleClose",
},
keys = {
{ "<leader>sd", "<cmd>Trouble workspace_diagnostics<cr>", silent = true, desc = "diagnostics workspace" },
{ "<leader>sD", "<cmd>Trouble document_diagnostics<cr>", silent = true, desc = "diagnostics document" },
},
},
-- testing setup
{
"nvim-neotest/neotest",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-treesitter/nvim-treesitter",
"antoinemadec/FixCursorHold.nvim",
"nvim-neotest/neotest-python",
},
config = function()
require("neotest").setup({
adapters = {
require("neotest-python")({
-- with coverage requires coverage.py and pytest-cov installed
args = { "--cov" },
}),
},
})
if require("util").is_available("which-key") then
require("which-key").register({ ["<localleader>t"] = { name = "+test" } })
end
end,
ft = { "python" },
keys = {
{
"<leader>st",
[[<cmd>lua require('neotest').summary.toggle()<cr>]],
desc = "toggle test list",
silent = true,
},
{
"<leader>sT",
[[<cmd>lua require('neotest').output_panel.toggle()<cr>]],
desc = "toggle test output",
silent = true,
},
{
"<localleader>to",
[[<cmd>lua require('neotest').output.open()<cr>]],
desc = "toggle test output",
silent = true,
},
{
"<localleader>tt",
[[<cmd>lua require('neotest').run.run()<cr>]],
desc = "run nearest test",
silent = true,
},
{
"<localleader>td",
[[<cmd>lua require('neotest').run.run({strategy = "dap"})<cr>]],
desc = "debug nearest test",
silent = true,
}, -- REQUIRES DAP
{
"<localleader>tT",
[[<cmd>lua require('neotest').run.run(vim.fn.expand("%"))<cr>]],
desc = "test current file",
silent = true,
},
{
"<localleader>tr",
[[<cmd>lua require('neotest').run.run_last()<cr>]],
desc = "re-run last test",
silent = true,
},
{
"<localleader>tw",
[[<cmd>lua require('neotest').watch.toggle()<cr>]],
desc = "watch current test",
silent = true,
},
{
"<localleader>tW",
[[<cmd>lua require('neotest').watch.toggle(vim.fn.expand("%"))<cr>]],
desc = "watch current file",
silent = true,
},
},
},
-- TODO needs to pick up poetry env for python,
-- currently just hard-codes running through poetry
{
"andythigpen/nvim-coverage",
dependencies = {
"nvim-lua/plenary.nvim",
},
config = function()
require("coverage").setup({
lang = { python = { coverage_command = "poetry run coverage json -q -o -" } },
})
end,
ft = { "python" },
cmd = {
"Coverage",
"CoverageLoad",
"CoverageLoadLcov",
"CoverageShow",
"CoverageHide",
"CoverageToggle",
"CoverageClear",
"CoverageSummary",
},
keys = {
{
"<localleader>tp",
[[<cmd>Coverage<cr>]],
desc = "show coverage report",
silent = true,
},
{
"<localleader>tP",
[[<cmd>CoverageToggle<cr>]],
desc = "toggle coverage gutter",
silent = true,
},
{
"<localleader>ts",
[[<cmd>CoverageSummary<cr>]],
desc = "show coverage summary",
silent = true,
},
},
},
}