nvim-lint icon indicating copy to clipboard operation
nvim-lint copied to clipboard

Use biome from node_modules when exists

Open mprytula opened this issue 5 months ago • 2 comments

Problem

I have biome installed with version 2.0.6 via mason for my personal projects, however on my work biome 1.9 is being used, so the config parser of biome 2.0.6 does not work properly.

Possible solution

Fetch biome from node_modules if exists, else use biome, installed globally. PS: Or maybe it's just my skill issue and there is a possibility to do it in current state.

mprytula avatar Jun 30 '25 21:06 mprytula

The default lint config already uses the locally installed version of biome, but: The lint message format seems to have changed in Biome 2, which is why there is no longer any output when using the biomejs-config from nvim-lint with Biome 2.x .

The lint message parsing has been fixed in https://github.com/mfussenegger/nvim-lint/pull/810, but this isn't merged yet.

You could (for the time being) simply overwrite your biomejs config.

Minimal lazy.nvim config

return {
 "mfussenegger/nvim-lint",
 event = { "BufReadPre", "BufNewFile" },
 config = function()
  local lint = require("lint")

  lint.linters_by_ft = {
   typescript = { "biomejs" },
  }

  local biome = lint.linters.biomejs

  lint.linters.biomejs = function()
   biome.args = { "lint", "--reporter=github" }
   biome.parser = function(output, bufnr, linter_cwd)
    local reporterGithubParser = require("lint.parser").from_pattern(
     "::(.+) title=(.+),file=(.+),line=(%d+),endLine=(%d+),col=(%d+),endColumn=(%d+)::(.+)",
     {
      "severity",
      "code",
      "file",
      "lnum",
      "end_lnum",
      "col",
      "end_col",
      "message",
     },
     {
      ["error"] = vim.diagnostic.severity.ERROR,
      ["warning"] = vim.diagnostic.severity.WARN,
      ["notice"] = vim.diagnostic.severity.INFO,
     },
     { ["source"] = "biomejs" },
     { lnum_offset = 0, end_lnum_offset = 0, end_col_offset = -1 }
    )

    -- when biomejs can't parse the file, the parse error does not look like the
    -- --reporter=github format, it is still important diagnostics, especially for json
    local parseErrorParser = function(output)
     local diagnostics = {}

     -- The diagnostic details we need are spread in the first 3 lines of
     -- each error report.  These variables are declared out of the FOR
     -- loop because we need to carry their values to parse multiple lines.
     local fetch_message = false
     local lnum, col, code, message

     -- When a lnum:col:code line is detected fetch_message is set to true.
     -- While fetch_message is true we will search for the error message.
     -- When a error message is detected, we will create the diagnostic and
     -- set fetch_message to false to restart the process and get the next
     -- diagnostic.
     for _, line in ipairs(vim.fn.split(output, "\n")) do
      if fetch_message then
       _, _, message = string.find(line, "%s×(.+)")

       if message then
        message = (message):gsub("^%s+×%s*", "")

        table.insert(diagnostics, {
         source = "biomejs",
         lnum = tonumber(lnum) - 1,
         col = tonumber(col),
         message = message,
         code = code,
        })

        fetch_message = false
       end
      else
       _, _, lnum, col, code = string.find(line, "[^:]+:(%d+):(%d+)%s([%a%/]+)")

       if lnum then
        fetch_message = true
       end
      end
     end

     return diagnostics
    end
    local result = reporterGithubParser(output, bufnr, linter_cwd)
    if #result ~= 0 then
     return result
    end

    result = parseErrorParser(output)
    return result
   end

   return biome
  end

  local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true })

  vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, {
   group = lint_augroup,
   callback = function()
    lint.try_lint()
   end,
  })
 end,
}

teicherus avatar Jul 10 '25 09:07 teicherus

It works for biome v2 output issue in neovim.

bruceunx avatar Aug 03 '25 09:08 bruceunx