From 3a406e632421e8d3124072bb9e335c931f0ebc4d Mon Sep 17 00:00:00 2001 From: charliie-dev Date: Wed, 22 Jul 2026 00:23:54 +0800 Subject: [PATCH 1/3] fix(lint): shrink the markdownlint override to args-only the from_pattern parser required path:line:col, but markdownlint omits the column when unknown (e.g. MD012), so those findings were silently dropped. inheriting upstream's stdin mode + errorformat parser (whose "stdin:%l %m" fallback keeps col-less findings) fixes that; the file-based shape is no longer needed now that mise ships real node. stdin also means the buffer's live content is linted instead of the on-disk file. only the --config arg pointing at the global .markdownlint.yml remains overridden. --- lua/modules/configs/completion/nvim-lint.lua | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/lua/modules/configs/completion/nvim-lint.lua b/lua/modules/configs/completion/nvim-lint.lua index f5bcf497..331d38b1 100644 --- a/lua/modules/configs/completion/nvim-lint.lua +++ b/lua/modules/configs/completion/nvim-lint.lua @@ -15,25 +15,17 @@ return function() "-", } end, - -- markdownlint-cli2: file-based mode + stderr parser date from the bun - -- node-shim era (stdin's for-await yielded empty); mise ships real node - -- now, so stdin likely works again — kept pending re-evaluation. - -- NOTE (known limitation): the pattern requires "path:line:col", but - -- upstream omits the column when unknown (e.g. MD012), so those - -- findings are silently dropped. + -- markdownlint-cli2: only add the global config — it discovers configs + -- upward from the linted file, so projects without their own would + -- otherwise fall back to factory defaults. stdin mode and the parser + -- stay upstream's; its errorformat fallback ("stdin:%l %m") keeps + -- findings whose column is unknown (e.g. MD012). ["markdownlint-cli2"] = function(linter) - linter.stdin = false linter.args = { "--config", vim.fn.stdpath("config") .. "/.markdownlint.yml", + "-", } - linter.stream = "stderr" - linter.parser = require("lint.parser").from_pattern( - "[^:]+:(%d+):(%d+) (%a+) (.+)", - { "lnum", "col", "severity", "message" }, - { ["error"] = vim.diagnostic.severity.ERROR, ["warning"] = vim.diagnostic.severity.WARN }, - { source = "markdownlint" } - ) end, } ---@param name string From fb11b6558677b21449f9675695c1b3f55008b4b3 Mon Sep 17 00:00:00 2001 From: charliie-dev Date: Wed, 22 Jul 2026 00:23:58 +0800 Subject: [PATCH 2/3] refactor(conform): drop the prettier temp-copy override MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the --write-on-temp-copy shape existed because the bun node-shim broke stdin; mise ships real node now and stdin works again, so conform's built-in prettier definition (stdin + --stdin-filepath) takes over — no more .conform.$RANDOM.* copy written per format. --- lua/modules/configs/completion/conform.lua | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lua/modules/configs/completion/conform.lua b/lua/modules/configs/completion/conform.lua index b58344c8..c01b7bed 100644 --- a/lua/modules/configs/completion/conform.lua +++ b/lua/modules/configs/completion/conform.lua @@ -163,16 +163,6 @@ return function() args = { "fix", "--stdin" }, stdin = true, }, - -- prettier: the --write-on-temp-copy shape dates from the bun - -- node-shim era (stdin was broken); mise ships real node now, so - -- stdin likely works again — kept pending re-evaluation. `stdin = - -- false` points $FILENAME at a `.conform.$RANDOM.*` copy; the real - -- file is never touched. - prettier = { - command = "prettier", - args = { "--write", "$FILENAME" }, - stdin = false, - }, }, format_on_save = format_on_save_enabled and function(bufnr) if not autoformat_allowed(bufnr) then From 8ca22097c28e1521c111d490821bfe98cd408fa5 Mon Sep 17 00:00:00 2001 From: charliie-dev Date: Wed, 22 Jul 2026 02:03:17 +0800 Subject: [PATCH 3/3] fix(conform): evaluate function-form commands at probe time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trusting a function-form command blindly as self-resolving let the prettier dep silently leave the install/warn contract: on a fresh machine with no node_modules copy and no global binary, nothing would ever install it or name it in the aggregated warning (a regression against main's ensure_installed loop). Evaluate the function against the probe-time buffer the way conform will: a project-local node_modules bin passes the $PATH check as-is, the bare-name fallback re-enters install/warn via the bin index, and a failed or non-string evaluation degrades to the previous self-resolving behavior — never a typo report. --- lua/modules/configs/completion/conform.lua | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lua/modules/configs/completion/conform.lua b/lua/modules/configs/completion/conform.lua index c01b7bed..dbe3e3a0 100644 --- a/lua/modules/configs/completion/conform.lua +++ b/lua/modules/configs/completion/conform.lua @@ -207,12 +207,23 @@ return function() return { broken = tostring(config) } end if config then - -- A function-form command resolves per buffer at format time (e.g. the - -- builtin from_node_modules): treat it as self-resolving rather than - -- evaluating it for a representative binary — a node_modules command - -- shouldn't map to a Mason install anyway. + -- A function-form command (the builtin from_node_modules) resolves per + -- buffer at format time, so evaluate it against the probe-time buffer + -- the same way conform will: a project-local node_modules bin passes + -- the $PATH check as-is, and the bare-name FALLBACK ("prettier") keeps + -- the dep inside the install/warn contract — trusting the function + -- blindly would let a fresh machine with no copy anywhere silently + -- skip both the Mason install and the aggregated warning. A failed or + -- non-string evaluation degrades to self-resolving (no install/warn), + -- never to a typo report. if type(config.command) == "function" then - return { binary = nil } + local fname = vim.api.nvim_buf_get_name(0) + local cmd_ok, cmd = pcall(config.command, config, { + buf = vim.api.nvim_get_current_buf(), + filename = fname, + dirname = fname ~= "" and vim.fs.dirname(fname) or vim.fn.getcwd(), + }) + return { binary = (cmd_ok and type(cmd) == "string" and cmd ~= "") and cmd or nil } end return { binary = config.command } end