From 995ecb11d38d92dcb403c74ebb71be3f4c834272 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Fri, 31 Jul 2026 13:18:30 -0400 Subject: [PATCH] Use the LazyVim oxc extra instead of hand-rolled oxlint config The oxlint LSP now enables type-aware linting on its own when tsgolint is present and .oxlintrc.json mentions typescript, and ships :LspOxlintFixAll -- which is what the oxlint_fix function reimplemented by shelling out to the CLI. The extra also sets fixKind = "all" and prefers the top-level oxlint config in monorepos. Fixes now apply as a workspace edit instead of writing to disk and reloading. oxfmt takes js/ts/json/vue over prettier; prettier keeps css/html/yaml/markdown. Add oxlint to mason so it resolves outside projects with a local install. Co-Authored-By: Claude Opus 5 --- lazyvim.json | 1 + lua/config/keymaps.lua | 59 --------------------------------------- lua/plugins/conform.lua | 24 ++++++++++++++++ lua/plugins/linting.lua | 9 ------ lua/plugins/lspconfig.lua | 49 +++++++++++++++++++------------- 5 files changed, 54 insertions(+), 88 deletions(-) create mode 100644 lua/plugins/conform.lua diff --git a/lazyvim.json b/lazyvim.json index 4d0cbd9..4c69c4e 100644 --- a/lazyvim.json +++ b/lazyvim.json @@ -29,6 +29,7 @@ "lazyvim.plugins.extras.lang.tex", "lazyvim.plugins.extras.lang.toml", "lazyvim.plugins.extras.lang.typescript", + "lazyvim.plugins.extras.lang.typescript.oxc", "lazyvim.plugins.extras.lang.typescript.tsgo", "lazyvim.plugins.extras.lang.typst", "lazyvim.plugins.extras.lang.yaml", diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index bc8bef0..d724a94 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -35,62 +35,3 @@ if vim.fn.has("mac") == 1 then vim.keymap.set("t", "", '"+pi') vim.keymap.set("t", "", '"+pi') end - -local function oxlint_cmd(bufnr) - local file = vim.api.nvim_buf_get_name(bufnr) - if file == "" then - return nil - end - - local root = vim.fs.dirname(vim.fs.find({ "package.json", ".oxlintrc.json", "oxlint.config.ts" }, { - path = file, - upward = true, - })[1] or "") - - local local_bin = root ~= "" and vim.fs.joinpath(root, "node_modules", ".bin", "oxlint") or nil - return local_bin and vim.fn.executable(local_bin) == 1 and local_bin or "oxlint" -end - -local function oxlint_fix() - local bufnr = vim.api.nvim_get_current_buf() - local file = vim.api.nvim_buf_get_name(bufnr) - if file == "" then - vim.notify("Oxlint fix requires a file-backed buffer", vim.log.levels.WARN) - return - end - - if vim.bo[bufnr].modified then - vim.cmd.update() - end - - local cmd = oxlint_cmd(bufnr) - if not cmd or vim.fn.executable(cmd) ~= 1 then - vim.notify("oxlint executable not found", vim.log.levels.ERROR) - return - end - - local cwd = vim.fs.dirname(vim.fs.find({ "package.json", ".oxlintrc.json", "oxlint.config.ts" }, { - path = file, - upward = true, - })[1] or file) - - vim.system({ cmd, "--fix", "--type-aware", file }, { cwd = cwd, text = true }, function(result) - vim.schedule(function() - if result.code == 0 or result.code == 1 then - vim.cmd.checktime() - pcall(require("lint").try_lint, "oxlint") - local level = result.code == 0 and vim.log.levels.INFO or vim.log.levels.WARN - local msg = result.code == 0 and "Oxlint fix completed" or "Oxlint fix completed with remaining diagnostics" - vim.notify(msg, level) - else - local output = table.concat(vim.tbl_filter(function(v) - return v and v ~= "" - end, { result.stdout, result.stderr }), "\n") - vim.notify(output ~= "" and output or "Oxlint fix failed", vim.log.levels.ERROR) - end - end) - end) -end - -vim.api.nvim_create_user_command("OxlintFix", oxlint_fix, { desc = "Fix current file with oxlint" }) -vim.keymap.set("n", "cx", oxlint_fix, { desc = "Oxlint Fix" }) diff --git a/lua/plugins/conform.lua b/lua/plugins/conform.lua new file mode 100644 index 0000000..cd446bd --- /dev/null +++ b/lua/plugins/conform.lua @@ -0,0 +1,24 @@ +local oxfmt_owned = { + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "json", + "jsonc", + "vue", +} + +return { + "stevearc/conform.nvim", + opts = function(_, opts) + opts.formatters_by_ft = opts.formatters_by_ft or {} + for _, ft in ipairs(oxfmt_owned) do + local formatters = opts.formatters_by_ft[ft] + if formatters then + opts.formatters_by_ft[ft] = vim.tbl_filter(function(formatter) + return formatter ~= "prettier" + end, formatters) + end + end + end, +} diff --git a/lua/plugins/linting.lua b/lua/plugins/linting.lua index f0fef61..6a1f292 100644 --- a/lua/plugins/linting.lua +++ b/lua/plugins/linting.lua @@ -1,16 +1,7 @@ return { "mfussenegger/nvim-lint", opts = { - linters_by_ft = { - javascript = { "oxlint" }, - typescript = { "oxlint" }, - javascriptreact = { "oxlint" }, - typescriptreact = { "oxlint" }, - }, linters = { - oxlint = { - prepend_args = { "--type-aware" }, - }, ["markdownlint-cli2"] = { prepend_args = { "--config", diff --git a/lua/plugins/lspconfig.lua b/lua/plugins/lspconfig.lua index c765c86..292a206 100644 --- a/lua/plugins/lspconfig.lua +++ b/lua/plugins/lspconfig.lua @@ -1,25 +1,34 @@ return { - "neovim/nvim-lspconfig", - opts = { - diagnostics = { - virtual_text = false, - virtual_lines = { current_line = true }, - }, - servers = { - clangd = { - -- removing .proto from the list of filetypes since clangd doesn't seem to be able to parse them - filetypes = { "c", "cpp", "objc", "objcpp", "cuda" }, + { + "neovim/nvim-lspconfig", + opts = { + diagnostics = { + virtual_text = false, + virtual_lines = { current_line = true }, + }, + servers = { + clangd = { + -- removing .proto from the list of filetypes since clangd doesn't seem to be able to parse them + filetypes = { "c", "cpp", "objc", "objcpp", "cuda" }, + }, + oxlint = { + keys = { + { "cx", "LspOxlintFixAll", desc = "Oxlint Fix All" }, + }, + }, + }, + -- Disable eslint formatting as it's slow and timing out on big projects + -- taken from + -- https://github.com/LazyVim/LazyVim/pull/4225/files + setup = { + eslint = function() + return + end, }, - -- Disable oxlint LSP - using nvim-lint with CLI instead for type-aware support - oxlint = { enabled = false }, - }, - -- Disable eslint formatting as it's slow and timing out on big projects - -- taken from - -- https://github.com/LazyVim/LazyVim/pull/4225/files - setup = { - eslint = function() - return - end, }, }, + { + "mason-org/mason.nvim", + opts = { ensure_installed = { "oxlint" } }, + }, }