Configuring and Extending Neovim
Prerequisites: Modules and require
Neovim embeds LuaJIT and exposes its whole API to Lua. Configuration
lives in ~/.config/nvim/init.lua (on Windows,
~/AppData/Local/nvim/init.lua).
Options, key mappings, and autocommands
-- illustrative
-- init.lua
vim.g.mapleader = " "
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.expandtab = true
vim.keymap.set("n", "<leader>w", "<cmd>write<cr>", {desc = "Save file"})
vim.keymap.set("n", "<leader>q", function()
vim.notify("Goodbye!")
vim.cmd("quit")
end, {desc = "Quit"})
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function() vim.highlight.on_yank({timeout = 200}) end,
})
require("config.lazy") -- loads lua/config/lazy.lua
vim.optsets options,vim.keymap.setdefines mappings (the right-hand side can be a Lua function), andvim.api.nvim_create_autocmdruns code on events.requirelooks in thelua/folder of your config, solua/config/lazy.luaisrequire("config.lazy").
A tiny plugin
-- illustrative
-- lua/todo/init.lua
local M = {}
function M.find()
local buf = vim.api.nvim_get_current_buf()
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
local items = {}
for i, line in ipairs(lines) do
if line:find("TODO") then
table.insert(items, {bufnr = buf, lnum = i, text = line})
end
end
vim.fn.setqflist(items)
vim.cmd("copen")
end
function M.setup(opts)
opts = opts or {}
vim.api.nvim_create_user_command("Todos", M.find, {})
vim.keymap.set("n", opts.key or "<leader>t", M.find, {desc = "List TODOs"})
end
return M
The setup(opts) convention lets users configure a plugin with
require("todo").setup({key = "<leader>T"}).
The ecosystem
- lazy.nvim — the most popular plugin manager.
vim.lsp— built-in Language Server Protocol client.vim.treesitter— syntax-aware highlighting and text objects.:help lua-guide— the official guide to Lua in Neovim.
Remember that Neovim runs LuaJIT: no integer division, <close>, or
other 5.3+ features.