LSP config not properly working

Hi everyone,

it’s a pleasure to join this discourse.
I would need your precious help.
So, I want to definitely abandon the all-time Neovim’s rival (the unmentionable :smile: )
I already quite got used to (Neo-)Vim built-in motions and custom remappings.
I’m now only missing a good (and minimalist) LSP integration.
I had firstly started with packer, but suffered very high startup times (around 5sec). And that was already a discouraging signal.
Then, I decided to move completely to Lazy package manager. There, starting with a minimal configuration, startup started to feel much smoother (though I still feel it hangs sometimes, specially at the very first launch after I shut down the machine).
Now, I cannot get the LSP to work properly.
As soon as I open the first buffer in a new Neovim session, I see the LSP init message appearing, meaning that the client rightly ataches to the buffer.
But then, none of the functionalities seem to work:

  1. If I introduce an error (whatever it is) the LSP doesn’t signal it (it used to in the past)
  2. The local buffer keymaps related to LSP do not work (i.e. if pressing ‘gd’ for going to the definition, it does not work, if not in the same file)

Here is my lazy.lua LSP config:

   -- LSP config
   {"neovim/nvim-lspconfig", 
      event = {"BufReadPre", "BufNewFile"},
      lazy = true,
      dependencies = {
         {"williamboman/mason.nvim"}, 
         {"williamboman/mason-lspconfig.nvim"},
         {"hrsh7th/nvim-cmp",
            dependencies = {
               "hrsh7th/cmp-nvim-lsp", 
               "hrsh7th/cmp-buffer",
               "hrsh7th/cmp-path", 
               "saadparwaiz1/cmp_luasnip",
               "L3MON4D3/LuaSnip", 
            }
         }
      },
      opts = {
         autoformat = false,  -- Automatically format on save
         format = {
            formatting_options = nil,
            timeout_ms = nil
         },
         -- LSP Server Settings
         servers = {
            fortls = {},
            clangd = {},
         },
      },
      config = function(_, opts)
         
         local luasnip = require("luasnip");
         local cmp = require'cmp'
         cmp.setup({
            snippet = {
               expand = function(args)
                  luasnip.lsp_expand(args.body)
               end,
            },
            window = {
               completion = cmp.config.window.bordered(),
               documentation = cmp.config.window.bordered(),
            },
            mapping = cmp.mapping.preset.insert({
               ['<C-n>'] = cmp.mapping.select_next_item(),
               ['<C-b>'] = cmp.mapping.select_prev_item(),
               ['<C-u>'] = cmp.mapping.scroll_docs(-2),
               ['<C-d>'] = cmp.mapping.scroll_docs(2),
               ['<C-Space>'] = cmp.mapping.complete(),
               ['<C-e>'] = cmp.mapping.abort(),
               ['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
               ['<Tab>'] = cmp.mapping(function(fallback)
                  if cmp.visible() then
                     cmp.select_next_item()
                  elseif luasnip.expand_or_locally_jumpable() then
                     luasnip.expand_or_jump()
                  else
                     fallback()
                  end
               end, { 'i', 's' }),
               ['<S-Tab>'] = cmp.mapping(function(fallback)
                  if cmp.visible() then
                     cmp.select_prev_item()
                  elseif luasnip.locally_jumpable(-1) then
                     luasnip.jump(-1)
                  else
                     fallback()
                  end
               end, { 'i', 's' }),
            }),
            sources = cmp.config.sources({
               { name = 'nvim_lsp' },
               { name = 'luasnip' },
               { name = "buffer" },
               { name = "path" },
            })
         })

         local servers = opts.servers
         local keymap_set = vim.keymap.set;

         local on_attach = function(_, bufnr)
            -- [[ Configure LSP ]]
            --  This function gets run when an LSP connects to a particular buffer.

            local nnoremap = function(keys, func, desc)
               if desc then
                  desc = 'LSP:  ' .. desc
               end
               keymap_set('n', keys, func, { buffer = bufnr, noremap = true, desc = desc });
            end
            
            nnoreamp('<leader>dm', vim.diagnostic.open_float, 'Open floating [d]iagnostic [m]essage' )
            nnoreamp("gp", vim.diagnostic.goto_prev, '[G]o to [p]revious diagnostic message' )
            nnoreamp("gn", vim.diagnostic.goto_next, '[G]o to [n]ext diagnostic message' )
            nnoreamp('<leader>dl', vim.diagnostic.setloclist, 'Open [d]iagnostics [l]ist' )

            nnoremap('gd', vim.lsp.buf.definition, '[G]oto [d]efinition')
            nnoremap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
            nnoremap('gi', vim.lsp.buf.implementation, '[G]oto [I]mplementation')
            nnoremap('gr', vim.lsp.buf.references, '[G]oto [R]eferences')
            nnoremap('K', vim.lsp.buf.hover, 'Hover documentation')
            nnoremap('<C-k>', vim.lsp.buf.signature_help, 'Signature Documentation')
            nnoremap('<space>wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder')
            nnoremap('<space>wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder')
            nnoremap('<space>wl', function()
               print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
            end, 'List [W]orkspace [F]olders')
            nnoremap('<leader>rn', vim.lsp.buf.rename, '[R]e[n]ame')
            nnoremap('<leader>D', vim.lsp.buf.type_definition, 'Type [D]efinition')
            nnoremap('<leader>f', function()
               vim.lsp.buf.format { async = true }
            end, 'Format current buffer')
            vim.keymap.set({ 'n', 'v' }, '<leader>ca', vim.lsp.buf.code_action, 
               {buffer = bufnr, noremap = true, desc = 'LSP:  [C]ode [A]ction'})
         end


         local lspconfig = require("lspconfig");
         local capabilities = require("cmp_nvim_lsp").default_capabilities(vim.lsp.protocol.make_client_capabilities())

         local function setup(server_name)
            local server_opts = {
               capabilities = capabilities,
               on_attach = on_attach,
               -- filetypes = (servers[server] or {}).filetypes,
            }
            lspconfig[server_name].setup(server_opts)
         end

         local mlsp = require("mason-lspconfig")
         local available = mlsp.get_available_servers()

         local ensure_installed = {}
         for server, server_opts in pairs(servers) do
            if server_opts then
               server_opts = server_opts == true and {} or server_opts
               -- run manual setup if mason=false or if this is a server that cannot be installed with mason-lspconfig
               if server_opts.mason == false or not vim.tbl_contains(available, server) then
                  setup(server)
               else
                  ensure_installed[#ensure_installed + 1] = server
               end
            end
         end

         require("mason").setup()
         require("mason-lspconfig").setup({
            ensure_installed = ensure_installed,
            automatic_installation = true
         })
         require("mason-lspconfig").setup_handlers({setup})
      end 
   },

Any suggestion is more than welcome.

Cheers