return {
  'neovim/nvim-lspconfig',
  dependencies = {
    -- "SmiteshP/nvim-navbuddy",
    -- "jubnzv/virtual-types.nvim",
    -- "ray-x/lsp_signature.nvim",
    -- 'sontungexpt/better-diagnostic-virtual-text',
    { url = "http://git.sr.ht/~p00f/clangd_extensions.nvim" },
  },
  config = function()
    require('clangd_extensions').setup({
      ast = {
        -- These are unicode, should be available in any font
        role_icons = {
          type = "🄣",
          declaration = "🄓",
          expression = "🄔",
          statement = ";",
          specifier = "🄢",
          ["template argument"] = "🆃",
        },
        kind_icons = {
          Compound = "🄲",
          Recovery = "🅁",
          TranslationUnit = "🅄",
          PackExpansion = "🄿",
          TemplateTypeParm = "🅃",
          TemplateTemplateParm = "🅃",
          TemplateParamObject = "🅃",
        },
        highlights = {
          detail = "Comment",
        },
        memory_usage = {
          border = "none",
        },
        symbol_info = {
          border = "none",
        }
      }
    })
    vim.lsp.enable('clangd_extensions')
    --local lsp_signature = require('lsp_signature')

    -- Mappings.
    vim.keymap.set('n', '<leader>e', vim.diagnostic.open_float)
    vim.keymap.set('n', '<leader>E', vim.diagnostic.setloclist)

    vim.lsp.inlay_hint.enable(true)

    -- Use an on_attach function to only map the following keys
    -- after the language server attaches to the current buffer
    vim.api.nvim_create_autocmd('LspAttach', {
      group = vim.api.nvim_create_augroup('UserLspConfig', {}),
      callback = function(ev)
        vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'

        -- See `:help vim.lsp.*` for documentation on any of the below functions
        local opts = { buffer = ev.buf }
        -- vim.keymap.del("n", "gra", opts)
        -- vim.keymap.del("v", "gra", opts)
        vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
        vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
        --def vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
        --vim.keymap.del("n", "grr", opts)
        --def vim.keymap.set('n', 'gri', vim.lsp.buf.implementation, opts)
        --def vim.keymap.set('n', 'gO', vim.lsp.buf.document_symbol, opts)
        --def vim.keymap.set('n', 'grn', vim.lsp.buf.rename, opts)
        --vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, opts)
        --vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, opts)
        --vim.keymap.set('n', '<space>wl', function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end, opts)
        vim.keymap.set('n', '<leader>D', vim.lsp.buf.type_definition, opts)
        vim.keymap.set('n', '<F6>', '<cmd>ClangdSwitchSourceHeader<CR>', opts)
        vim.keymap.set("n", "<leader>q", function() vim.lsp.buf.format { async = true } end, opts)

        -- require 'virtualtypes'.on_attach()
        -- require'lsp_signature'.on_attach({
        --   floating_window = true,
        --   floating_window_above_cur_line = true,
        --   floating_window_off_x = 10,
        --   floating_window_off_y = 0,
        -- })
        -- require("better-diagnostic-virtual-text.api").setup_buf(ev.buf, {
        --   ui = {
        --     wrap_line_after = false, -- wrap the line after this length to avoid the virtual text is too long
        --     left_kept_space = 3,     --- the number of spaces kept on the left side of the virtual text, make sure it enough to custom for each line
        --     right_kept_space = 3,    --- the number of spaces kept on the right side of the virtual text, make sure it enough to custom for each line
        --     arrow = "  ",
        --     up_arrow = "  ",
        --     down_arrow = "  ",
        --     above = false, -- the virtual text will be displayed above the line
        --   },
        --   priority = 2003, -- the priority of virtual text
        --   inline = true
        -- })

        vim.diagnostic.config({
          underline = false,
          signs = {
            text = {
              [vim.diagnostic.severity.HINT]  = "",
              [vim.diagnostic.severity.ERROR] = "✘",
              [vim.diagnostic.severity.INFO]  = "◉",
              [vim.diagnostic.severity.WARN]  = ""
            }
          },
          virtual_text = false,
          update_in_insert = false,
          severity_sort = true,
          -- virtual_lines = {
          --   current_line = true,
          -- }
        })
      end
    })

    --local capabilities = vim.lsp.protocol.make_client_capabilities()
    --local capabilities = require('cmp_nvim_lsp').default_capabilities()
    local capabilities = require('blink.cmp').get_lsp_capabilities()
    -- local capabilities = vim.tbl_deep_extend('force',
    --   vim.lsp.protocol.make_client_capabilities(),
    --   require('epo').register_cap()
    -- )
    --capabilities.offsetEncoding = { "utf-16" }

    vim.lsp.config('groovyls', {
      cmd = { "java", "-jar", "/home/kmcr/tools/groovy-language-server/build/libs/groovy-language-server-all.jar" },
      capabilities = capabilities
    })

    vim.lsp.config('clangd_extensions', {
      cmd = {
        "/workspace/WayveCode/tools/clangd",
        "--background-index",
        "-j=32",
        "--header-insertion=never"},
      capabilities = capabilities,
      filetypes = { "cpp" },
    })

    vim.lsp.config('pylsp', {
      settings = {
        pylint = {
          enabled = true
        },
        pyflakes = {
          enabled = true,
        },
      },
      capabilities = capabilities
    })

    vim.lsp.config('lua_ls', {
      settings = {
        Lua = {
          diagnostics = { globals = { "vim" } },
          completion = {
            callSnippet = "Replace"
          }
        }
      }
    })

    -- nvim_lsp.matlab_ls.setup({
    --   cmd = { "matlab-language-server", "--stdio" },
    --   filetypes = { "matlab" },
    --   -- root_dir = nvim_lsp.util.find_git_ancestor,
    --   root_dir = vim.fs.dirname(vim.fs.find('.git',
    --     { path = vim.fs.dirname(vim.api.nvim_buf_get_name(0)), upward = true })[1]),
    --   single_file_support = true,
    --   settings = {
    --     matlab = {
    --       -- indexWorkspace = false,
    --       installPath = "/usr/local/MATLAB/R2024b",
    --       -- matlabConnectionTiming = "onStart",
    --       -- telemetry = true,
    --     },
    --   }
    -- })

    vim.lsp.config('typos_lsp', {
      cmd = { 'typos-lsp' },
      filetypes = { '*' },
      root_dir = require("lspconfig.util").root_pattern('typos.toml', '_typos.toml', '.typos.toml'),
      single_file_support = true,
      settings = {},
    })

    vim.lsp.config('bzl', {
      cmd = { 'bzl', 'lsp', 'serve' },
      filetypes = { 'bzl' },
      -- https://docs.bazel.build/versions/5.4.1/build-ref.html#workspace
      root_markers = { 'WORKSPACE', 'WORKSPACE.bazel' },
    })

    vim.lsp.config('rust_analyzer', {
      cmd = { 'rust_analyzer'},
      filetypes = { "rust" },
      single_file_support = true,
      settings = {},
    })
    vim.lsp.enable('rust_analyzer')

    -- Use a loop to conveniently call 'setup' on multiple servers and
    -- map buffer local keybindings when the language server attaches
    local servers = { "cmake", "rust_analyzer", "bashls", "marksman", "bzl" }
    for _, lsp in ipairs(servers) do
      vim.lsp.config(lsp, {
        capabilities = capabilities,
      })
    end
  end
}
