local M = {} M.root_patterns = { ".git", "/lua" } ---@param on_attach fun(client, buffer) function M.on_attach(on_attach) vim.api.nvim_create_autocmd("LspAttach", { callback = function(args) local buffer = args.buf local client = vim.lsp.get_client_by_id(args.data.client_id) on_attach(client, buffer) end, }) end -- returns the root directory based on: -- * lsp workspace folders -- * lsp root_dir -- * root pattern of filename of the current buffer -- * root pattern of cwd ---@return string function M.get_root() ---@type string? local path = vim.api.nvim_buf_get_name(0) path = path ~= "" and vim.loop.fs_realpath(path) or nil ---@type string[] local roots = {} if path then for _, client in pairs(vim.lsp.get_active_clients({ bufnr = 0 })) do local workspace = client.config.workspace_folders local paths = workspace and vim.tbl_map(function(ws) return vim.uri_to_fname(ws.uri) end, workspace) or client.config.root_dir and { client.config.root_dir } or {} for _, p in ipairs(paths) do local r = vim.loop.fs_realpath(p) if path:find(r, 1, true) then roots[#roots + 1] = r end end end end table.sort(roots, function(a, b) return #a > #b end) ---@type string? local root = roots[1] if not root then path = path and vim.fs.dirname(path) or vim.loop.cwd() ---@type string? root = vim.fs.find(M.root_patterns, { path = path, upward = true })[1] root = root and vim.fs.dirname(root) or vim.loop.cwd() end ---@cast root string return root end function M.telescope(builtin, opts) return function() require("telescope.builtin")[builtin](vim.tbl_deep_extend("force", { cwd = M.get_root() }, opts or {})) end end -- Opens a floating terminal (interactive by default) ---@param cmd? string[]|string ---@param opts? LazyCmdOptions|{interactive?:boolean} function M.float_term(cmd, opts) opts = vim.tbl_deep_extend("force", { size = { width = 0.9, height = 0.9 }, }, opts or {}) require("lazy.util").float_term(cmd, opts) end ---@param silent boolean? ---@param values? {[1]:any, [2]:any} function M.toggle(option, silent, values) if values then if vim.opt_local[option]:get() == values[1] then vim.opt_local[option] = values[2] else vim.opt_local[option] = values[1] end return vim.notify( "Set " .. option .. " to " .. vim.opt_local[option]:get(), vim.log.levels.INFO, { title = "Option" } ) end vim.opt_local[option] = not vim.opt_local[option]:get() if not silent then vim.notify( (vim.opt_local[option]:get() and "Enabled" or "Disabled") .. " " .. option, vim.log.levels.INFO, { title = "Option" } ) end end local enabled = true function M.toggle_diagnostics() enabled = not enabled if enabled then vim.diagnostic.enable() vim.notify("Enabled diagnostics", vim.log.levels.INFO, { title = "Diagnostics" }) else vim.diagnostic.disable() vim.notify("Disabled diagnostics", vim.log.levels.INFO, { title = "Diagnostics" }) end end return M