This commit is contained in:
inorishio
2026-02-10 16:13:55 +01:00
parent f77acb5f33
commit 4c8248f323
8 changed files with 318 additions and 334 deletions
-219
View File
@@ -2,9 +2,7 @@ local M = {}
M.plugin = {
"sbdchd/neoformat",
event = { "BufReadPre", "BufNewFile" },
config = function()
-- === formatter enablement (order = priority) ===
vim.g.neoformat_enabled_lua = { "stylua" }
vim.g.neoformat_enabled_python = { "black" }
vim.g.neoformat_enabled_javascript = { "prettier" }
@@ -15,223 +13,6 @@ M.plugin = {
vim.g.neoformat_enabled_bash = { "shfmt" }
vim.g.neoformat_enabled_zsh = { "shfmt" }
vim.g.neoformat_enabled_powershell = { "pwshfmt" } -- experimental
-- === helper to prefer local prettier in cwd/node_modules/.bin ===
local function prefer_local_prettier()
local cwd = vim.fn.getcwd()
local local_path = cwd .. "/node_modules/.bin/prettier"
if vim.loop.fs_stat(local_path) then
return local_path
end
local global = vim.fn.exepath("prettier")
if global ~= "" then
return global
end
return "prettier"
end
-- === neoformatters definitions ===
vim.g.neoformatters_javascript = {
prettier = {
exe = prefer_local_prettier(),
args = { "--stdin-filepath", "%:p" },
stdin = 1,
},
}
vim.g.neoformatters_typescript = vim.g.neoformatters_javascript
vim.g.neoformatters_json = vim.g.neoformatters_javascript
vim.g.neoformatters_markdown = vim.g.neoformatters_javascript
vim.g.neoformatters_lua = {
stylua = {
exe = "stylua",
args = { "-", "--stdin-filepath", "%:p" },
stdin = 1,
},
}
vim.g.neoformatters_python = {
black = {
exe = "black",
args = { "-" },
stdin = 1,
},
}
vim.g.neoformatters_qml = {
qmlformat = {
exe = "qmlformat",
args = { "-" },
stdin = 1,
},
}
vim.g.neoformatters_go = {
gofmt = {
exe = "gofmt",
args = {},
stdin = 1,
},
}
vim.g.neoformatters_sh = {
shfmt = {
exe = "shfmt",
args = { "-i", "2", "-ci" },
stdin = 1,
},
}
vim.g.neoformatters_bash = vim.g.neoformatters_sh
vim.g.neoformatters_zsh = vim.g.neoformatters_sh
vim.g.neoformatters_powershell = {
pwshfmt = {
exe = "pwsh",
args = {
"-NoProfile",
"-Command",
[[
$in = [Console]::In.ReadToEnd();
if (Get-Command Invoke-Formatter -ErrorAction SilentlyContinue) {
Invoke-Formatter -ScriptDefinition $in | Out-String
} else {
$in
}
]],
},
stdin = 1,
},
}
-- === utility: check whether a path/exe exists ===
local function is_executable(path)
if not path or path == "" then
return false
end
-- if it contains a slash or backslash, treat as path
if path:match("[/\\]") then
local stat = vim.loop.fs_stat(path)
return stat and stat.type == "file"
end
-- otherwise check PATH
return vim.fn.exepath(path) ~= ""
end
local function resolve_exe_field(exe_field)
if type(exe_field) == "function" then
local ok, res = pcall(exe_field)
if ok then
return res
else
return nil
end
end
if type(exe_field) == "string" then
return exe_field
end
return nil
end
-- === determine whether any configured formatter for ft is available ===
local function has_formatter_for_ft(ft)
if not ft or ft == "" then
return false
end
-- 1) check explicit enabled list first
local enabled_var = "neoformat_enabled_" .. ft
local enabled = vim.g[enabled_var]
local candidates = {}
if enabled then
if type(enabled) == "string" then
candidates = { enabled }
elseif type(enabled) == "table" then
candidates = enabled
end
else
-- 2) fallback to any entries defined in vim.g.neoformatters_<ft>
local table_var = "neoformatters_" .. ft
local tbl = vim.g[table_var]
if type(tbl) == "table" then
for name, _ in pairs(tbl) do
table.insert(candidates, name)
end
end
end
if #candidates == 0 then
return false
end
-- table of custom formatter definitions
local formatter_table = vim.g["neoformatters_" .. ft]
for _, name in ipairs(candidates) do
-- if we have a definition with exe, check that exe
if formatter_table and formatter_table[name] and formatter_table[name].exe then
local exe_field = formatter_table[name].exe
local exe = resolve_exe_field(exe_field)
if exe and is_executable(exe) then
return true
end
else
-- otherwise, try to find a system executable by the formatter name
if is_executable(name) then
return true
end
end
end
return false
end
-- === safe format wrapper that no-ops when no formatter found ===
local function neoformat_if_available(bufnr)
bufnr = bufnr or 0
local ft = vim.bo[bufnr].filetype
if not has_formatter_for_ft(ft) then
-- silent fallback: do nothing if no formatter is available
return
end
-- run Neoformat in protected call to avoid blocking save on errors
pcall(vim.cmd, "Neoformat")
end
-- === keymap and command using the safe wrapper ===
vim.keymap.set("n", "<leader>f", function()
neoformat_if_available()
end, { noremap = true, silent = true })
vim.api.nvim_create_user_command("NeoformatIfAvailable", function()
neoformat_if_available()
end, {})
-- === autoreformat on save (uses safe wrapper) ===
local format_on_save_filetypes = {
lua = true,
python = true,
javascript = true,
typescript = true,
qml = true,
go = true,
sh = true,
bash = true,
zsh = true,
powershell = false, -- keep off by default (experimental)
}
vim.api.nvim_create_autocmd("BufWritePre", {
group = vim.api.nvim_create_augroup("NeoformatOnSave", { clear = true }),
callback = function(args)
local ft = vim.bo[args.buf].filetype
if format_on_save_filetypes[ft] then
neoformat_if_available(args.buf)
end
end,
})
-- === end config ===
end,
}