From a8e496f73e48b4830be19a8f686ec18535dbd885 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sat, 10 Sep 2022 14:03:08 +0200 Subject: [PATCH] feat: easier way to work with setting patterns --- lua/settings/commands.lua | 6 ++-- lua/settings/config.lua | 39 +++++++++++++++++++++-- lua/settings/plugins/jsonls.lua | 2 +- lua/settings/plugins/lspconfig.lua | 2 +- lua/settings/util.lua | 50 ++++++++++++++++++++++++------ lua/settings/workspace.lua | 3 +- 6 files changed, 83 insertions(+), 19 deletions(-) diff --git a/lua/settings/commands.lua b/lua/settings/commands.lua index ad42691..fd47b88 100644 --- a/lua/settings/commands.lua +++ b/lua/settings/commands.lua @@ -37,7 +37,7 @@ function M.setup() local group = vim.api.nvim_create_augroup("Settings", { clear = true }) vim.api.nvim_create_autocmd("BufWritePost", { - pattern = Util.merge({}, Config.options.global_settings, vim.tbl_values(Config.options.local_settings)), + pattern = Util.file_patterns(), group = group, callback = function(event) local fname = Util.fqn(event.match) @@ -61,11 +61,11 @@ function M.get_files(opts) if not opts.global then local root_dir = require("settings.workspace").find_root({ lsp = true }) Util.for_each_local(function(f) - items[f] = { file = f } + table.insert(items, { file = f }) end, root_dir) end - return vim.tbl_values(items) + return items end function M.edit(opts) diff --git a/lua/settings/config.lua b/lua/settings/config.lua index bd386b2..c315ffa 100644 --- a/lua/settings/config.lua +++ b/lua/settings/config.lua @@ -1,9 +1,9 @@ local M = {} ---- @class Config +---@class Config M.defaults = { - local_settings = { ".nvim.settings.json", vscode = ".vscode/settings.json" }, - global_settings = { "nvim.settings.json" }, + local_settings = ".nvim.settings.json", + global_settings = "nvim.settings.json", plugins = { lspconfig = { enabled = true, @@ -26,8 +26,41 @@ M.defaults = { --- @type Config M.options = {} +---@class SettingsPattern +---@field pattern string +---@field key string|nil|fun(string):string + +---@type SettingsPattern[] +M.local_patterns = {} + +---@type SettingsPattern[] +M.global_patterns = {} + function M.setup(options) M.options = vim.tbl_deep_extend("force", {}, M.defaults, options or {}) + + local util = require("settings.util") + + M.local_patterns = {} + M.global_patterns = {} + + if M.options.import.vscode then + table.insert(M.local_patterns, { pattern = ".vscode/settings.json", key = "vscode" }) + end + if M.options.import.coc then + table.insert(M.local_patterns, { pattern = "coc-settings.json", key = "coc" }) + table.insert(M.global_patterns, { pattern = "coc-settings.json", key = "coc" }) + end + if M.options.import.nlsp then + local function nlsp_key(file) + return "nlsp." .. vim.fn.fnamemodify(file, ":t:r") + end + table.insert(M.local_patterns, { pattern = ".nlsp-settings/*.json", key = nlsp_key }) + table.insert(M.global_patterns, { pattern = "nlsp-settings/*.json", key = nlsp_key }) + end + + vim.list_extend(M.local_patterns, util.expand(M.options.local_settings)) + vim.list_extend(M.global_patterns, util.expand(M.options.global_settings)) end ---@return Config diff --git a/lua/settings/plugins/jsonls.lua b/lua/settings/plugins/jsonls.lua index 4ad5b8d..43fb886 100644 --- a/lua/settings/plugins/jsonls.lua +++ b/lua/settings/plugins/jsonls.lua @@ -45,7 +45,7 @@ function M.on_new_config(config, root_dir) }, type = "object", }, - fileMatch = { table.unpack(Config.options.global_settings), table.unpack(Config.options.local_settings) }, + fileMatch = Util.file_patterns(), } for _, plugin in ipairs(require("settings.plugins").plugins) do diff --git a/lua/settings/plugins/lspconfig.lua b/lua/settings/plugins/lspconfig.lua index 3ee35d8..6c919f8 100644 --- a/lua/settings/plugins/lspconfig.lua +++ b/lua/settings/plugins/lspconfig.lua @@ -8,7 +8,7 @@ function M.setup() local lsputil = require("lspconfig.util") local hook = lsputil.add_hook_before - local settings_root = lsputil.root_pattern(unpack(vim.tbl_values(Config.options.local_settings))) + local settings_root = lsputil.root_pattern(unpack(Util.file_patterns({ global = false }))) lsputil.on_setup = hook(lsputil.on_setup, function(config) config.on_new_config = hook(config.on_new_config, Util.protect(M.on_new_config, "Failed to setup lspconfig")) diff --git a/lua/settings/util.lua b/lua/settings/util.lua index d39df62..d45b562 100644 --- a/lua/settings/util.lua +++ b/lua/settings/util.lua @@ -22,6 +22,25 @@ function M.merge(...) return ret end +function M.file_patterns(opts) + opts = M.merge({ ["local"] = true, ["global"] = true }, opts) + local ret = {} + + if opts["local"] then + for _, p in ipairs(Config.local_patterns) do + table.insert(ret, p.pattern) + end + end + + if opts["global"] then + for _, p in ipairs(Config.global_patterns) do + table.insert(ret, p.pattern) + end + end + + return ret +end + function M.path(str) local f = debug.getinfo(1, "S").source:sub(2) return M.fqn(vim.fn.fnamemodify(f, ":h:h:h") .. "/" .. (str or "")) @@ -87,24 +106,37 @@ function M.is_nvim_config(path) return M.has_file(M.fqn(path), M.config_path()) end ----@param patterns table ----@param fn fun(file: string|nil, key:string|nil, pattern:string) +---@param patterns SettingsPattern[] +---@param fn fun(file: string, key:string|nil, pattern:string) +---@param root_dir string function M.for_each(patterns, fn, root_dir) - for key, pattern in pairs(patterns) do - if type(key) == "number" then - key = nil + for _, p in ipairs(patterns) do + local file = root_dir .. "/" .. p.pattern + ---@diagnostic disable-next-line: param-type-mismatch + for _, f in pairs(vim.fn.expand(file, false, true)) do + ---@diagnostic disable-next-line: param-type-mismatch + fn(f, type(p.key) == "function" and p.key(f) or p.key, p.pattern) end - local file = root_dir and root_dir .. "/" .. pattern - fn(file, key, pattern) end end +---@param patterns string|(string|SettingsPattern)[] +---@return SettingsPattern[] +function M.expand(patterns) + return vim.tbl_map(function(p) + return type(p) == "string" and { pattern = p } or p + end, type(patterns) == "table" and patterns or { patterns }) +end + +---@param root_dir string +---@param fn fun(file: string, key:string|nil, pattern:string) function M.for_each_local(fn, root_dir) - M.for_each(Config.options.local_settings, fn, root_dir) + M.for_each(Config.local_patterns, fn, root_dir) end +---@param fn fun(file: string, key:string|nil, pattern:string) function M.for_each_global(fn) - M.for_each(Config.options.global_settings, fn, vim.fn.stdpath("config")) + M.for_each(Config.global_patterns, fn, vim.fn.stdpath("config")) end function M.is_global(file) diff --git a/lua/settings/workspace.lua b/lua/settings/workspace.lua index 21579b0..272381f 100644 --- a/lua/settings/workspace.lua +++ b/lua/settings/workspace.lua @@ -1,5 +1,4 @@ local Util = require("settings.util") -local Config = require("settings.config") local Settings = require("settings.settings") local lsputil = require("lspconfig.util") @@ -18,7 +17,7 @@ function M.find_root(opts) local fname = Util.fqn(opts.file or vim.api.nvim_buf_get_name(buf)) -- find the root dir that contains a local settings file - local root_dir = lsputil.root_pattern(unpack(vim.tbl_values(Config.options.local_settings)))(fname) + local root_dir = lsputil.root_pattern(unpack(Util.file_patterns({ global = false })))(fname) -- fallback to lsp root_dir detection if in options if not root_dir and opts.lsp then