irongit

filetype configs with named files. has telescope

124 lines2.9 KBLua
1local M = {}
2M.filetypes = {}
3M.ftdir = vim.fn.stdpath("config") .. "/lua/ftconfig"
4
5if vim.fn.isdirectory(M.ftdir) == 0 then
6 vim.fn.mkdir(M.ftdir, "p")
7end
8
9local 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
20function M.set_keymaps(ft, spec)
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
31end
32
33---sets the indent
34---@param ft string
35---@param spec FTSpec
36function M.set_indent(ft, spec)
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 })
47end
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
56function M.set_conform(ft, spec)
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
61end
62
63---sets up lsps
64---@param spec FTSpec
65function M.set_lsp(spec)
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
74end
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
84function M.load_file(filename)
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
103end
104
105---creates a new filetype and begins to edit it
106---@param ft string
107function M.edit_filetype(ft)
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")
113end
114
115function M.setup()
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")
122end
123
124return M