Created
June 23, 2025 01:17
-
-
Save AlexBeauchemin/0f3a32e1ecff802de4a611ef7fe4d517 to your computer and use it in GitHub Desktop.
Run biome linter and send result to quickfix list
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local function find_biome_executable() | |
local cwd = vim.fn.getcwd() | |
-- Check for local biome executable in node_modules | |
local paths_to_check = { | |
cwd .. "/node_modules/.bin/biome", | |
cwd .. "/../node_modules/.bin/biome", | |
cwd .. "/../../node_modules/.bin/biome", | |
} | |
for _, path in ipairs(paths_to_check) do | |
if vim.fn.executable(path) == 1 then | |
return path | |
end | |
end | |
-- Fallback to npx if not found | |
return "npx @biomejs/biome" | |
end | |
-- Run biome lint and send report to quickfix | |
local function biome_lint() | |
local file = vim.fn.expand("%") | |
local biome_cmd = find_biome_executable() | |
print("🚀 Launching Biome's linter") | |
-- Redirect stderr to /dev/null to hide the warning | |
local cmd = biome_cmd .. " lint --diagnostic-level=error --reporter=json" | |
if file then | |
cmd = cmd .. " " .. vim.fn.shellescape(file) | |
end | |
cmd = cmd .. " 2>/dev/null" | |
local output = vim.fn.system(cmd) | |
if vim.trim(output) == "" then | |
print("No Biome issues found") | |
vim.fn.setqflist({}) | |
return | |
end | |
local ok, json_data = pcall(vim.fn.json_decode, output) | |
if not ok then | |
print("Failed to parse Biome JSON output") | |
return | |
end | |
local qf_list = {} | |
if json_data.diagnostics then | |
for _, diagnostic in ipairs(json_data.diagnostics) do | |
local location = diagnostic.location | |
if location and location.path then | |
-- Parse line/column from span and source code | |
local line = 1 | |
local col = 1 | |
if location.span and location.sourceCode then | |
local start_pos = location.span[1] | |
local source_lines = vim.split(location.sourceCode, "\n") | |
local char_count = 0 | |
for line_num, line_content in ipairs(source_lines) do | |
if char_count + #line_content >= start_pos then | |
line = line_num | |
col = start_pos - char_count + 1 | |
break | |
end | |
char_count = char_count + #line_content + 1 -- +1 for newline | |
end | |
end | |
table.insert(qf_list, { | |
filename = location.path.file, | |
lnum = line, | |
col = col, | |
type = diagnostic.severity == "error" and "E" or "W", | |
text = diagnostic.category .. ": " .. diagnostic.description, | |
}) | |
end | |
end | |
end | |
vim.fn.setqflist(qf_list) | |
if #qf_list > 0 then | |
vim.cmd("copen") | |
print("Found " .. #qf_list .. " Biome issue(s)") | |
else | |
print("No Biome issues found") | |
end | |
end | |
vim.api.nvim_create_user_command("BiomeLint", biome_lint, {}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment