vimtricks.wiki Concise Vim tricks, one at a time.

How do I set buffer-local keymaps that only activate when an LSP server attaches to a buffer in Neovim?

Answer

vim.api.nvim_create_autocmd('LspAttach', ...)

Explanation

Setting your LSP keymaps inside a LspAttach autocmd ensures they are only active in buffers where a language server is actually running. Global keymaps that call vim.lsp.buf.* functions fail silently (or not so silently) in buffers without LSP. The LspAttach event fires every time a server connects to a buffer, giving you the buffer number and client ID so you can set scoped mappings.

How it works

  • vim.api.nvim_create_autocmd('LspAttach', { callback = fn }) registers a function called on each attach
  • opts.buf inside the callback is the buffer number the server attached to
  • Passing buffer = bufnr to vim.keymap.set() makes the mapping buffer-local and automatically removed when the buffer is wiped

Example

vim.api.nvim_create_autocmd('LspAttach', {
  callback = function(opts)
    local bufnr = opts.buf
    local map = function(lhs, rhs, desc)
      vim.keymap.set('n', lhs, rhs, { buffer = bufnr, desc = desc })
    end

    map('K',           vim.lsp.buf.hover,       'LSP hover')
    map('gd',          vim.lsp.buf.definition,   'Go to definition')
    map('gr',          vim.lsp.buf.references,   'Go to references')
    map('<leader>rn',  vim.lsp.buf.rename,       'Rename symbol')
    map('<leader>ca',  vim.lsp.buf.code_action,  'Code action')
  end,
})

Tips

  • Access the client with vim.lsp.get_client_by_id(opts.data.client_id) to guard capability-specific keymaps: if client:supports_method('textDocument/rename') then
  • Add group = vim.api.nvim_create_augroup('MyLsp', { clear = true }) to the autocmd opts to prevent duplicate registrations when your config is reloaded
  • This pattern works alongside both vim.lsp.enable() (Neovim 0.11+) and nvim-lspconfig

Next

What is the difference between the inner word (iw) and inner WORD (iW) text objects in Vim?