Configuring Neovim with Lua: Part 2

3 minute read

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:

  1. mode: the mode the keymap will be configured for
  2. lhs-keymap: the keys that will trigger the keymap
  3. rhs-keymap: the sequence of keys, functions, etc that get invoked when the “lhs-keymap” keys get pressed
  4. opts: optional keymap parameters such as silent or noremap

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!

References

comments powered by Disqus