| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- local M = {
- formatters = {
- lsp = {},
- filetype = {}
- },
- commands = {}
- }
- M.setup = function()
- local group = vim.api.nvim_create_augroup("SaveFormatter", { clear = true })
- vim.api.nvim_create_autocmd({ "BufWritePost" }, {
- group = group,
- pattern = { "*" },
- 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
- --- @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
- 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
- end
- ---@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
- ---@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
- ---@param name string
- ---@param value function
- M.command = function(name, value)
- M.commands[name] = value
- end
- 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(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 displayer = entry_display.create({
- separator = " ▏",
- 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.name }, { entry.enabled }, { command } })
- end,
- ordinal = entry.name
- }
- end
- }),
- sorter = conf.generic_sorter({}),
- attach_mappings = function(buf, _)
- actions.select_default:replace(function()
- 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 M
|