Configuring Neovim with Lua: Part 2
Intro
Hello, 🌎! In part 1 of this “Configuring Neovim with Lua” series, I demonstrated how we can set Vim options using Lua. In this post, I’ll provide a foundation for creating your custom keymaps for Neovim using Lua and the Nvim API.
File Placement
In part 1, we created a file in $HOME/.config/nvim/lua/profile/
called keymaps.lua
. If you have done that already, then what are you waiting for!
Make sure you also have an init file at:
$HOME/.config/nvim/init.lua
And that it imports keymaps.lua
like this:
File: init.lua
require 'profile.options'
require 'profile.keymaps' -- <<<---
require 'profile.plugins'
Creating Keymaps with the Nvim API
The Nvim API provides a function called nvim_set_keymap
which we can use to set our custom keymaps. The nvim_set_keymap
function takes in 4 parameters in the following order:
- mode: the mode the keymap will be configured for
- lhs-keymap: the keys that will trigger the keymap
- rhs-keymap: the sequence of keys, functions, etc that get invoked when the “lhs-keymap” keys get pressed
- opts: optional keymap parameters such as
silent
ornoremap
That’s pretty much all we need to know about this function to start creating keymaps.
So open up $HOME/.config/nvim/lua/profile/keymaps.lua
and enter the following lines of Lua code:
local opts = {
noremap = true, -- non-recursive mapping, execute the mapped keys as they are
silent = true, -- don't show mapped key output, if any
}
local keymap = vim.api.nvim_set_keymap
The opts
table will be passed as the fourth argument to our keymap
function which now points to vim.api.nvim_set_keymap
. Before writing our first keymap, here is a table that defines the most common modes you’ll most likely configure a keymap for:
Mode | Mode Identifier |
---|---|
Normal | n |
Insert | i |
Visual | v |
Visual Line | V |
Command | c |
Terminal | t |
Replace | R |
We are now equip to create our first keymap! The first keymap we’ll create is properly the most popular mapping which changes the way we exit from insert mode.
keymap("i", "jj", "<esc>", opts)
This keymapping now allows me to type jj
to exit insert mode.
If you want to use a leader key in your keymaps, first set the mapleader
and maplocalleader
global variables to what you want your leader key to be like this:
vim.g.mapleader = ","
vim.g.maplocalleader = ","
And then use it in your keymappings like this:
keymap("i", "<leader>jj", "<esc>", opts)
Now you can types ,jj
and that will trigger the exit from insert mode.
Your keymaps.lua
file should now look like this, if you followed along:
NOTE: single-line comments in Lua begin with
--
local opts = {
noremap = true,
silent = true,
}
local keymap = vim.api.nvim_set_keymap
vim.g.mapleader = ","
vim.g.maplocalleader = ","
-- remap `jj` to ESC in insert mode
keymap("i", "jj", "<esc>", opts)
-- keymap("i", "<leader>jj", "<esc>", opts) -- for those that want to use leader key
With that information, you should now be able to create your own Neovim keymappings using Lua!
For reference, here is what my keymaps.lua
looks like:
local opts = {
noremap = true,
silent = true,
}
local keymap = vim.api.nvim_set_keymap
vim.g.mapleader = ","
vim.g.maplocalleader = ","
-- remap `jj` to ESC in insert mode
keymap("i", "jj", "<esc>", opts)
-- move between windows quicker
keymap("n", "<C-h>", "<C-w>h", opts)
keymap("n", "<C-j>", "<C-w>j", opts)
keymap("n", "<C-k>", "<C-w>k", opts)
keymap("n", "<C-l>", "<C-w>l", opts)
-- resize windows with arrow keys
keymap("n", "<C-UP>", ":resize +2<cr>", opts)
keymap("n", "<C-Down>", ":resize -2<cr>", opts)
keymap("n", "<C-Left>", ":vertical resize +2<cr>", opts)
keymap("n", "<C-Right>", ":vertical resize -2<cr>", opts)
keymap("n", "<leader>db", ":normal gg<s-v>Gd<cr>", opts)
keymap("n", "<leader>dfl", "<s-v>ggd<cr>", opts)
keymap("n", "<leader>dll", "<s-v>Gd<cr>", opts)
-- FZF
keymap("n", "<leader>ff", ":FZF<cr>", opts)
-- NvimTree
keymap("n", "<leader>t", ":NvimTreeToggle<cr>", opts)
keymap("n", "<leader>r", ":NvimTreeRefresh<cr>", opts)
-- Barbar
keymap("n", "<leader>bp", ":BufferPrevious<cr>", opts)
keymap("n", "<leader>bn", ":BufferNext<cr>", opts)
keymap("n", "<leader>bc", ":BufferClose<cr>", opts)
-- exit terminal with ESC
keymap("t", "<esc>", "<c-\\><c-n>:q!<esc>", opts)
keymap("i", "<leader>pi", "<esc>:PasteImg<cr>", opts)
-- Rust.vim
keymap("n", "<leader>rr", ":RustRun<cr>", opts)
keymap("n", "<leader>rf", ":RustFmt<cr>", opts)
-- Coc.nvim
keymap("n", "<leader>gd", "<Plug>(coc-definition)", opts)
keymap("n", "<leader>gy", "<Plug>(coc-type-definition)", opts)
keymap("n", "<leader>gi", "<Plug>(coc-implementation)", opts)
keymap("n", "<leader>gr", "<Plug>(coc-references)", opts)
-- keymap("", "", "", opts)
EOF
If you enjoyed reading this blog and learned something, keep an eye out for more of my posts and maybe consider following me on GitHub, where I work on cybersecurity projects. And if you are feeling really generous, consider buying me a coffee!