| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 | local M = {}local tbl = require "lvim.utils.table"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  if not client_id then    local buf_clients = vim.lsp.buf_get_clients()    for _, buf_client in pairs(buf_clients) do      if buf_client.name ~= "null-ls" then        client = buf_client        break      end    end  else    client = vim.lsp.get_client_by_id(tonumber(client_id))  end  if not client then    error "Unable to determine client_id"    return  end  local enabled_caps = {}  for capability, status in pairs(client.server_capabilities or client.resolved_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)  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_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 avalable_formatters = s.get_available(filetype, method)  if #avalable_formatters > 0 then    return client.name == "null-ls"  elseif client.supports_method "textDocument/formatting" then    return true  else    return false  endend---Provide vim.lsp.buf.format for nvim <0.8---@param opts tablefunction M.format(opts)  opts = opts or {}  opts.filter = opts.filter or M.format_filter  if vim.lsp.buf.format then    return vim.lsp.buf.format(opts)  end  local bufnr = opts.bufnr or vim.api.nvim_get_current_buf()  ---@type table|nil  local clients = vim.lsp.get_active_clients {    id = opts.id,    bufnr = bufnr,    name = opts.name,  }  if opts.filter then    clients = vim.tbl_filter(opts.filter, clients)  end  clients = vim.tbl_filter(function(client)    return client.supports_method "textDocument/formatting"  end, clients)  if #clients == 0 then    vim.notify_once "[LSP] Format request failed, no matching language servers."  end  local timeout_ms = opts.timeout_ms or 1000  for _, client in pairs(clients) do    local params = vim.lsp.util.make_formatting_params(opts.formatting_options)    local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr)    if result and result.result then      vim.lsp.util.apply_text_edits(result.result, bufnr, client.offset_encoding)    elseif err then      vim.notify(string.format("[LSP][%s] %s", client.name, err), vim.log.levels.WARN)    end  endendreturn M
 |