How do I define key mappings in Neovim using Lua instead of the old Vimscript API?
Answer
vim.keymap.set
Explanation
vim.keymap.set is Neovim's modern Lua function for creating key mappings. Unlike the older vim.api.nvim_set_keymap, it accepts Lua functions directly as the right-hand side and defaults to noremap = true, eliminating the most common source of mapping bugs.
How it works
vim.keymap.set(mode, lhs, rhs, opts)
- mode: a string (
'n','i','v','x','t',''for all modes) or a list of modes - lhs: the key sequence to bind, e.g.
'<leader>f' - rhs: a string command OR a Lua function
- opts: an optional table with
desc,silent,noremap,buffer,expr
Example
-- Map <leader>w to save, silently
vim.keymap.set('n', '<leader>w', '<cmd>write<CR>', { desc = 'Save file', silent = true })
-- Map to a Lua function — not possible with the old API as a string
vim.keymap.set('n', '<leader>t', function()
print('current file: ' .. vim.fn.expand('%'))
end, { desc = 'Show current file' })
-- Buffer-local mapping (e.g., inside an LSP on_attach callback)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, { buffer = 0, desc = 'Go to definition' })
Tips
- The
descfield integrates with plugins like which-key.nvim to show mapping descriptions noremap = trueis the default — passremap = trueto allow recursive mappings- Pass a list of modes to map the same key in multiple modes:
{ 'n', 'v' } buffer = 0means the current buffer;buffer = Ntargets buffer number N- Use
vim.keymap.del(mode, lhs, opts)to remove a mapping programmatically