filetype configs with named files. has telescope
| 1 | local M = {} |
| 2 | M.filetypes = {} |
| 3 | M.ftdir = vim.fn.stdpath("config") .. "/lua/ftconfig" |
| 4 | |
| 5 | if vim.fn.isdirectory(M.ftdir) == 0 then |
| 6 | vim.fn.mkdir(M.ftdir, "p") |
| 7 | end |
| 8 | |
| 9 | local augroup = vim.api.nvim_create_augroup("ftconfig", { clear = true }) |
| 10 | |
| 11 | ---@class ft.KeymapOptions |
| 12 | ---@field [1] string # mode |
| 13 | ---@field [2] string # lhs |
| 14 | ---@field [3] string|fun(args:vim.api.keyset.create_autocmd.callback_args) # rhs |
| 15 | ---@field [4]? vim.keymap.set.Opts |
| 16 | |
| 17 | ---sets the keymaps |
| 18 | ---@param ft string |
| 19 | ---@param spec FTSpec |
| 20 | |
| 21 | for _, k in ipairs(spec.keymaps or {}) do |
| 22 | vim.api.nvim_create_autocmd("FileType", { |
| 23 | pattern = ft, |
| 24 | callback = function(args) |
| 25 | local opts = k[4] or {} |
| 26 | opts.buffer = args.buf |
| 27 | vim.keymap.set(k[1], k[2], k[3], opts) |
| 28 | end, |
| 29 | }) |
| 30 | end |
| 31 | end |
| 32 | |
| 33 | ---sets the indent |
| 34 | ---@param ft string |
| 35 | ---@param spec FTSpec |
| 36 | |
| 37 | local indent = spec.indent or 4 |
| 38 | vim.api.nvim_create_autocmd("FileType", { |
| 39 | group = augroup, |
| 40 | pattern = ft, |
| 41 | callback = function() |
| 42 | vim.opt_local.shiftwidth = indent |
| 43 | vim.opt_local.tabstop = indent |
| 44 | vim.opt_local.softtabstop = indent |
| 45 | end, |
| 46 | }) |
| 47 | end |
| 48 | |
| 49 | ---@class ft.ConformSpec |
| 50 | ---@field use string[] |
| 51 | ---@field formatters? table<string, conform.FileFormatterConfig> |
| 52 | |
| 53 | ---sets conform |
| 54 | ---@param ft string |
| 55 | ---@param spec FTSpec |
| 56 | |
| 57 | if spec.conform then |
| 58 | local conform_opts = { formatters_by_ft = { [ft] = spec.conform.use }, formatters = spec.conform.formatters } |
| 59 | require("conform").setup(conform_opts) |
| 60 | end |
| 61 | end |
| 62 | |
| 63 | ---sets up lsps |
| 64 | ---@param spec FTSpec |
| 65 | |
| 66 | if spec.lsp then |
| 67 | for key, value in pairs(spec.lsp) do |
| 68 | if value.enabled == nil or value.enabled then |
| 69 | vim.lsp.config(key, value) |
| 70 | vim.lsp.enable(key) |
| 71 | end |
| 72 | end |
| 73 | end |
| 74 | end |
| 75 | |
| 76 | ---@class FTSpec |
| 77 | ---@field indent? integer |
| 78 | ---@field conform? ft.ConformSpec |
| 79 | ---@field keymaps? ft.KeymapOptions[] |
| 80 | ---@field lsp? ft.LSPConf |
| 81 | |
| 82 | ---Loads the config for the given filename |
| 83 | ---@param filename string |
| 84 | |
| 85 | local ft = vim.fn.fnamemodify(filename, ":r") |
| 86 | table.insert(M.filetypes, ft) |
| 87 | local mod = "ftconfig." .. ft |
| 88 | ---@type FTSpec? |
| 89 | local spec = require(mod) |
| 90 | if spec == nil or type(spec) == "boolean" then |
| 91 | return |
| 92 | end |
| 93 | local ok, err = pcall(function() |
| 94 | M.set_indent(ft, spec) |
| 95 | M.set_keymaps(ft, spec) |
| 96 | M.set_conform(ft, spec) |
| 97 | M.set_lsp(spec) |
| 98 | end) |
| 99 | if not ok then |
| 100 | local msg = string.format("%s ftconfig error: %s", ft, err) |
| 101 | vim.notify(msg, vim.log.levels.ERROR) |
| 102 | end |
| 103 | end |
| 104 | |
| 105 | ---creates a new filetype and begins to edit it |
| 106 | ---@param ft string |
| 107 | |
| 108 | local filename = M.ftdir .. "/" .. ft .. ".lua" |
| 109 | if vim.fn.filereadable(filename) == 0 then |
| 110 | table.insert(M.filetypes, ft) |
| 111 | end |
| 112 | vim.cmd("edit " .. M.ftdir .. "/" .. ft .. ".lua") |
| 113 | end |
| 114 | |
| 115 | |
| 116 | for _, file in ipairs(vim.fn.readdir(M.ftdir)) do |
| 117 | if file:match("%.lua") then |
| 118 | M.load_file(file) |
| 119 | end |
| 120 | end |
| 121 | require("ftconfig.commands") |
| 122 | end |
| 123 | |
| 124 | return M |