Open3
Conform.nvimでdeno fmtとprettierを出しわける
Node.jsとDenoの出し分けはいろんな方が記事を出しているしよく使うので汎用関数に切り分ける
~/.config/nvim/lua/utils.lua
local M = {}
function M.get_js_runtime(bufnr)
local bufname = vim.fs.normalize(vim.api.nvim_buf_get_name(bufnr))
local dir = vim.fs.dirname(bufname)
local findopts = { upward = true, path = dir }
local deno_files = vim.fs.find({ "deno.json", "deno.jsonc", "deno.lock" }, findopts)
local node_files = vim.fs.find({ "package.json" }, findopts)
return {
is_deno = #deno_files > 0,
is_node = #node_files > 0,
deno_root_dir = #deno_files > 0 and vim.fs.dirname(deno_files[1]) or dir,
node_root_dir = #node_files > 0 and vim.fs.dirname(node_files[1]) or dir,
}
end
return M
ちなみにLSPでは以下のように使う
~/.config/nvim/after/lsp/denols.lua
---@type vim.lsp.Config
return {
single_file_support = true,
workspace_required = true,
root_markers = {},
root_dir = function(bufnr, cb)
local js_runtime = require("utils").get_js_runtime(bufnr)
local enabled = js_runtime.is_deno
or (not js_runtime.is_node and vim.bo.filetype ~= "markdown")
if enabled then
return cb(js_runtime.deno_root_dir)
end
end,
}
一旦こんな感じで。Lazy.nvimで構成しています。
- 同じように切り分けたい FileTypeがいくつかあるので列挙してまとめて設定する
-
stop_after_first = true: 複数のフォーマッターが同時に使われるのを防ぐ- Go で
gofmtとgoimportsを同時に走らせたいときとかにはこの設定をしない方が良さそう
- Go で
-
lsp_format = "fallback": 該当のフォーマッターがなければ Language Server のフォーマッターにフォールバックする- 他に
neverやpreferなどがある
- 他に
conform_nvim.lua
local js_formatter = function(bufnr)
local js_runtime = require("utils").get_js_runtime(bufnr)
if js_runtime.is_deno or not js_runtime.is_node then
return {}
else
return { "biome", "prettierd", "prettier", stop_after_first = true }
end
end
---@type LazyPluginSpec
return {
"stevearc/conform.nvim",
event = { "BufReadPre", "BufNewFile" },
opts = function()
local js_fts = vim.lsp.config["denols"].filetypes or {
"javascript",
"javascriptreact",
"javascript.jsx",
"typescript",
"typescriptreact",
"typescript.tsx",
"json",
"jsonc",
}
local formatters_by_ft = {}
for _, ft in ipairs(js_fts) do
formatters_by_ft[ft] = js_formatter
end
return {
default_format_opts = {
lsp_format = "fallback",
},
format_on_save = {
lsp_format = "fallback",
},
formatters_by_ft = formatters_by_ft,
}
end,
}