| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 | local M = {}local tbl = require "lvim.utils.table"local Log = require "lvim.core.log"function M.is_client_active(name)  local clients = vim.lsp.get_active_clients()  return tbl.find_first(clients, function(client)    return client.name == name  end)endfunction M.get_active_clients_by_ft(filetype)  local matches = {}  local clients = vim.lsp.get_active_clients()  for _, client in pairs(clients) do    local supported_filetypes = client.config.filetypes or {}    if client.name ~= "null-ls" and vim.tbl_contains(supported_filetypes, filetype) then      table.insert(matches, client)    end  end  return matchesendfunction M.get_client_capabilities(client_id)  local client = vim.lsp.get_client_by_id(tonumber(client_id))  if not client then    Log:warn("Unable to determine client from client_id: " .. client_id)    return  end  local enabled_caps = {}  for capability, status in pairs(client.server_capabilities) do    if status == true then      table.insert(enabled_caps, capability)    end  end  return enabled_capsend---Get supported filetypes per server---@param server_name string can be any server supported by nvim-lsp-installer---@return string[] supported filestypes as a list of stringsfunction M.get_supported_filetypes(server_name)  local status_ok, config = pcall(require, ("lspconfig.server_configurations.%s"):format(server_name))  if not status_ok then    return {}  end  return config.default_config.filetypes or {}end---Get supported servers per filetype---@param filter { filetype: string | string[] }?: (optional) Used to filter the list of server names.---@return string[] list of names of supported serversfunction M.get_supported_servers(filter)  local _, supported_servers = pcall(function()    return require("mason-lspconfig").get_available_servers(filter)  end)  return supported_servers or {}end---Get all supported filetypes by nvim-lsp-installer---@return string[] supported filestypes as a list of stringsfunction M.get_all_supported_filetypes()  local status_ok, filetype_server_map = pcall(require, "mason-lspconfig.mappings.filetype")  if not status_ok then    return {}  end  return vim.tbl_keys(filetype_server_map or {})endfunction M.setup_document_highlight(client, bufnr)  if lvim.builtin.illuminate.active then    Log:debug "skipping setup for document_highlight, illuminate already active"    return  end  local status_ok, highlight_supported = pcall(function()    return client.supports_method "textDocument/documentHighlight"  end)  if not status_ok or not highlight_supported then    return  end  local group = "lsp_document_highlight"  local hl_events = { "CursorHold", "CursorHoldI" }  local ok, hl_autocmds = pcall(vim.api.nvim_get_autocmds, {    group = group,    buffer = bufnr,    event = hl_events,  })  if ok and #hl_autocmds > 0 then    return  end  vim.api.nvim_create_augroup(group, { clear = false })  vim.api.nvim_create_autocmd(hl_events, {    group = group,    buffer = bufnr,    callback = vim.lsp.buf.document_highlight,  })  vim.api.nvim_create_autocmd("CursorMoved", {    group = group,    buffer = bufnr,    callback = vim.lsp.buf.clear_references,  })endfunction M.setup_document_symbols(client, bufnr)  vim.g.navic_silence = false -- can be set to true to suppress error  local symbols_supported = client.supports_method "textDocument/documentSymbol"  if not symbols_supported then    Log:debug("skipping setup for document_symbols, method not supported by " .. client.name)    return  end  local status_ok, navic = pcall(require, "nvim-navic")  if status_ok then    navic.attach(client, bufnr)  endendfunction M.setup_codelens_refresh(client, bufnr)  local status_ok, codelens_supported = pcall(function()    return client.supports_method "textDocument/codeLens"  end)  if not status_ok or not codelens_supported then    return  end  local group = "lsp_code_lens_refresh"  local cl_events = { "BufEnter", "InsertLeave" }  local ok, cl_autocmds = pcall(vim.api.nvim_get_autocmds, {    group = group,    buffer = bufnr,    event = cl_events,  })  if ok and #cl_autocmds > 0 then    return  end  vim.api.nvim_create_augroup(group, { clear = false })  vim.api.nvim_create_autocmd(cl_events, {    group = group,    buffer = bufnr,    callback = vim.lsp.codelens.refresh,  })end---filter passed to vim.lsp.buf.format---always selects null-ls if it's available and caches the value per buffer---@param client table client attached to a buffer---@return boolean if client matchesfunction M.format_filter(client)  local filetype = vim.bo.filetype  local n = require "null-ls"  local s = require "null-ls.sources"  local method = n.methods.FORMATTING  local available_formatters = s.get_available(filetype, method)  if #available_formatters > 0 then    return client.name == "null-ls"  elseif client.supports_method "textDocument/formatting" then    return true  else    return false  endend---Simple wrapper for vim.lsp.buf.format() to provide defaults---@param opts table|nilfunction M.format(opts)  opts = opts or {}  opts.filter = opts.filter or M.format_filter  return vim.lsp.buf.format(opts)endreturn M
 |