|
|
@@ -1,145 +1,151 @@
|
|
|
-local commands = {
|
|
|
- prettier =
|
|
|
- [[!prettier --write --ignore-path $XDG_CONFIG_HOME/prettier/ignore --config $XDG_CONFIG_HOME/prettier/config %:p]],
|
|
|
- deno = [[!deno fmt %:p]],
|
|
|
- ruff = [[!ruff format %:p]],
|
|
|
+local M = {
|
|
|
+ formatters = {
|
|
|
+ lsp = {},
|
|
|
+ filetype = {}
|
|
|
+ },
|
|
|
+ commands = {}
|
|
|
}
|
|
|
|
|
|
-local default = {
|
|
|
- json = commands.prettier,
|
|
|
- jsonc = commands.prettier,
|
|
|
- html = commands.prettier,
|
|
|
- css = commands.prettier,
|
|
|
- markdown = commands.prettier,
|
|
|
- denols = commands.deno,
|
|
|
- python = commands.ruff,
|
|
|
- typescriptreact = true,
|
|
|
- lua_ls = true,
|
|
|
-}
|
|
|
-local enabled = {}
|
|
|
-
|
|
|
-local save_format = function(source)
|
|
|
- if enabled[source] ~= nil then
|
|
|
- if enabled[source] == true then
|
|
|
- vim.api.nvim_exec("lua vim.lsp.buf.format()", true)
|
|
|
- vim.api.nvim_exec("noautocmd write", true)
|
|
|
- else
|
|
|
- vim.api.nvim_exec(enabled[source], true)
|
|
|
- end
|
|
|
- end
|
|
|
- vim.api.nvim_exec("e", true)
|
|
|
-end
|
|
|
-
|
|
|
-local global_autocmd_group = vim.api.nvim_create_augroup("SaveFormatterGlobal",
|
|
|
- { clear = true })
|
|
|
-local setup = function()
|
|
|
+M.setup = function()
|
|
|
+ local group = vim.api.nvim_create_augroup("SaveFormatter", { clear = true })
|
|
|
vim.api.nvim_create_autocmd({ "BufWritePost" }, {
|
|
|
+ group = group,
|
|
|
pattern = { "*" },
|
|
|
- group = global_autocmd_group,
|
|
|
- callback = function()
|
|
|
- for _, lsp_data in pairs(vim.lsp.get_active_clients()) do
|
|
|
- for buf_num, buf_active in pairs(lsp_data.attached_buffers) do
|
|
|
- if buf_num == vim.api.nvim_get_current_buf() and buf_active ==
|
|
|
- true and enabled[lsp_data.name] then
|
|
|
- save_format(lsp_data.name)
|
|
|
- return
|
|
|
- end
|
|
|
- end
|
|
|
- end
|
|
|
- if enabled[vim.bo.filetype] ~= nil then
|
|
|
- save_format(vim.bo.filetype)
|
|
|
+ callback = function(args) M.format(args.buf, true) end
|
|
|
+ })
|
|
|
+ vim.api.nvim_create_autocmd({ "BufWritePre" }, {
|
|
|
+ group = group,
|
|
|
+ pattern = { "*" },
|
|
|
+ callback = function(args) M.format(args.buf, false) end
|
|
|
+ })
|
|
|
+ vim.api.nvim_create_autocmd({ "LspAttach" }, {
|
|
|
+ group = group,
|
|
|
+ callback = function(args)
|
|
|
+ local client = vim.lsp.get_client_by_id(args.data.client_id)
|
|
|
+ if client ~= nil and client:supports_method('textDocument/format') then
|
|
|
+ M.add("lsp", client.name, nil, false)
|
|
|
end
|
|
|
end
|
|
|
})
|
|
|
end
|
|
|
|
|
|
-local enable = function(items)
|
|
|
- if not items then
|
|
|
- enabled = vim.deepcopy(default)
|
|
|
- else
|
|
|
- enabled = vim.deepcopy(items)
|
|
|
+--- @param buf integer
|
|
|
+--- @param did_write boolean
|
|
|
+M.format = function(buf, did_write)
|
|
|
+ local filetype = vim.bo[buf].filetype
|
|
|
+ local lsps = vim.lsp.get_clients({ bufnr = buf })
|
|
|
+
|
|
|
+ for _, client in pairs(lsps) do
|
|
|
+ if M.formatters.lsp[client.name] ~= nil and M.formatters.lsp[client.name].enabled then
|
|
|
+ if not did_write then
|
|
|
+ vim.lsp.buf.format({ bufnr = buf })
|
|
|
+ end
|
|
|
+ return
|
|
|
+ end
|
|
|
end
|
|
|
- for key, value in pairs(enabled) do
|
|
|
- if value == false then
|
|
|
- enabled[key] = nil
|
|
|
+ if M.formatters.filetype[filetype] ~= nil and M.formatters.filetype[filetype].enabled and M.commands[M.formatters.filetype[filetype].command] ~= nil then
|
|
|
+ M.commands[M.formatters.filetype[filetype].command](buf)
|
|
|
+ if did_write then
|
|
|
+ vim.api.nvim_buf_call(buf, function()
|
|
|
+ vim.api.nvim_exec2("noautocmd edit", {})
|
|
|
+ end)
|
|
|
end
|
|
|
end
|
|
|
- return enabled
|
|
|
end
|
|
|
-local disable = function()
|
|
|
- default = vim.deepcopy(enabled)
|
|
|
- enabled = {}
|
|
|
- return enabled
|
|
|
+
|
|
|
+---@param type "lsp"|"filename"
|
|
|
+---@param name string
|
|
|
+---@param enabled boolean
|
|
|
+M.toggle = function(type, name, enabled)
|
|
|
+ if M.formatters[type] == nil or M.formatters[type][name] == nil then return end
|
|
|
+ if enabled == nil then
|
|
|
+ M.formatters[type][name].enabled = not M.formatters[type][name].enabled
|
|
|
+ else
|
|
|
+ M.formatters[type][name].enabled = enabled
|
|
|
+ end
|
|
|
end
|
|
|
-local add = function(item, value)
|
|
|
- if value == nil then value = vim.deepcopy(default[item]) end
|
|
|
- enabled[item] = vim.deepcopy(value)
|
|
|
- return value
|
|
|
+
|
|
|
+---@param type "lsp"|"filetype"
|
|
|
+---@param name string
|
|
|
+---@param command string|nil
|
|
|
+---@param enable boolean|nil
|
|
|
+M.add = function(type, name, command, enable)
|
|
|
+ if M.formatters[type] == nil then return end
|
|
|
+ local formatter = { enabled = false }
|
|
|
+ if type == "filetype" then
|
|
|
+ if command == nil then return end
|
|
|
+ formatter.command = command
|
|
|
+ end
|
|
|
+ if enable then formatter.enabled = true end
|
|
|
+ if M.formatters[type][name] ~= nil then
|
|
|
+ formatter.enabled = M.formatters[type][name].enabled
|
|
|
+ end
|
|
|
+ M.formatters[type][name] = formatter
|
|
|
end
|
|
|
-local remove = function(item)
|
|
|
- default[item] = vim.deepcopy(enabled[item])
|
|
|
- enabled[item] = nil
|
|
|
+
|
|
|
+---@param name string
|
|
|
+---@param value function
|
|
|
+M.command = function(name, value)
|
|
|
+ M.commands[name] = value
|
|
|
end
|
|
|
|
|
|
-local pickers = require("telescope.pickers")
|
|
|
-local themes = require("telescope.themes")
|
|
|
-local actions = require("telescope.actions")
|
|
|
-local action_state = require("telescope.actions.state")
|
|
|
-local finders = require("telescope.finders")
|
|
|
-local conf = require("telescope.config").values
|
|
|
-local entry_display = require("telescope.pickers.entry_display")
|
|
|
-local picker = function(opts)
|
|
|
+M.picker = function()
|
|
|
+ if pcall(require, "telescope.pickers") then else return end
|
|
|
+ local pickers = require("telescope.pickers")
|
|
|
+ local themes = require("telescope.themes")
|
|
|
+ local actions = require("telescope.actions")
|
|
|
+ local action_state = require("telescope.actions.state")
|
|
|
+ local finders = require("telescope.finders")
|
|
|
+ local conf = require("telescope.config").values
|
|
|
+ local entry_display = require("telescope.pickers.entry_display")
|
|
|
+
|
|
|
local items = {}
|
|
|
- for key, value in pairs(enabled) do
|
|
|
- if value ~= nil then
|
|
|
- table.insert(items, { key, value })
|
|
|
- end
|
|
|
+ for key, value in pairs(M.formatters.lsp) do
|
|
|
+ table.insert(items, {
|
|
|
+ type = "lsp",
|
|
|
+ name = key,
|
|
|
+ enabled = value.enabled
|
|
|
+ })
|
|
|
+ end
|
|
|
+ for key, value in pairs(M.formatters.filetype) do
|
|
|
+ table.insert(items, {
|
|
|
+ type = "filetype",
|
|
|
+ name = key,
|
|
|
+ enabled = value.enabled,
|
|
|
+ command = value.command
|
|
|
+ })
|
|
|
end
|
|
|
pickers.new(themes.get_dropdown({}), {
|
|
|
prompt_title = "Save Formatter",
|
|
|
finder = finders.new_table({
|
|
|
results = items,
|
|
|
entry_maker = function(entry)
|
|
|
- local desc = "LSP Format"
|
|
|
- if type(entry[2]) == "string" then desc = entry[2] end
|
|
|
local displayer = entry_display.create({
|
|
|
separator = " ▏",
|
|
|
- items = { { width = 16 }, { remaining = true } }
|
|
|
+ items = { { width = 32 }, { width = 8 }, { remaining = true } }
|
|
|
})
|
|
|
+ local command = "LSP"
|
|
|
+ if entry.command ~= nil then command = entry.command end
|
|
|
return {
|
|
|
value = entry,
|
|
|
- display = function() return displayer({ { entry[1] }, { desc } }) end,
|
|
|
- ordinal = entry[1],
|
|
|
+ display = function()
|
|
|
+ return displayer({ { entry.name }, { entry.enabled }, { command } })
|
|
|
+ end,
|
|
|
+ ordinal = entry.name
|
|
|
}
|
|
|
- end,
|
|
|
+ end
|
|
|
}),
|
|
|
- sorter = conf.generic_sorter(opts),
|
|
|
- attach_mappings = function(prompt_bufnr, map)
|
|
|
- map("n", "d", function(_)
|
|
|
- local entry = action_state.get_selected_entry()
|
|
|
- if entry ~= nil then
|
|
|
- remove(entry.value[1])
|
|
|
- actions.close(prompt_bufnr)
|
|
|
- end
|
|
|
- end)
|
|
|
+ sorter = conf.generic_sorter({}),
|
|
|
+ attach_mappings = function(buf, _)
|
|
|
actions.select_default:replace(function()
|
|
|
- if add(action_state.get_current_line()) ~= nil then
|
|
|
- actions.close(prompt_bufnr)
|
|
|
- end
|
|
|
+ local t = action_state.get_selected_entry().value
|
|
|
+ M.formatters[t.type][t.name].enabled = not t.enabled
|
|
|
+ actions.close(buf)
|
|
|
+ M.picker()
|
|
|
end)
|
|
|
return true
|
|
|
end
|
|
|
}):find()
|
|
|
end
|
|
|
|
|
|
-return {
|
|
|
- add = add,
|
|
|
- disable = disable,
|
|
|
- enable = enable,
|
|
|
- picker = picker,
|
|
|
- remove = remove,
|
|
|
- setup = setup,
|
|
|
- commands = function() return commands end,
|
|
|
- default = function() return default end,
|
|
|
- enabled = function() return enabled end,
|
|
|
-}
|
|
|
+return M
|