Lua Session 03: Neovim API
Neovim-specific Lua. This session covers the vim namespace for options, keymaps, commands, and autocommands.
Pre-Session State
-
Understand Lua tables
-
Can use ipairs/pairs iteration
-
Know function syntax
Lesson 1: vim.opt (Options)
Concept: vim.opt sets Neovim options with Lua syntax.
Exercise 1.1: Basic options
-- Number and boolean options
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.tabstop = 4
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
-- Check current value
print(vim.opt.tabstop:get())
Exercise 1.2: List options
-- Append to list
vim.opt.wildignore:append({ "*.pyc", "node_modules" })
-- Prepend to list
vim.opt.path:prepend({ "**" })
-- Remove from list
vim.opt.wildignore:remove({ "*.pyc" })
Exercise 1.3: Local options
-- Buffer-local
vim.bo.filetype = "lua"
vim.bo.tabstop = 2
-- Window-local
vim.wo.number = true
vim.wo.wrap = false
-- Both available via vim.opt_local
vim.opt_local.spell = true
Lesson 2: vim.keymap (Keybindings)
Concept: vim.keymap.set is the modern way to create keymaps.
Exercise 2.1: Basic keymaps
-- vim.keymap.set(mode, lhs, rhs, opts)
-- Normal mode
vim.keymap.set('n', '<leader>w', ':w<CR>', { desc = 'Save file' })
-- Insert mode
vim.keymap.set('i', 'jk', '<Esc>', { desc = 'Exit insert mode' })
-- Visual mode
vim.keymap.set('v', '<', '<gv', { desc = 'Indent and reselect' })
Exercise 2.2: Lua function keymaps
-- Call Lua function
vim.keymap.set('n', '<leader>h', function()
print("Hello from Lua!")
end, { desc = 'Say hello' })
-- With parameters
vim.keymap.set('n', '<leader>p', function()
local filename = vim.fn.expand('%')
print("Current file: " .. filename)
end, { desc = 'Print filename' })
Exercise 2.3: Keymap options
vim.keymap.set('n', '<leader>q', ':q<CR>', {
desc = 'Quit',
silent = true, -- Don't show command
noremap = true, -- Don't remap recursively
buffer = 0, -- Buffer-local (0 = current)
})
Lesson 3: vim.api (Low-level API)
Concept: vim.api provides the full Neovim API.
Exercise 3.1: Buffer operations
-- Get current buffer
local buf = vim.api.nvim_get_current_buf()
print("Buffer: " .. buf)
-- Get buffer name
local name = vim.api.nvim_buf_get_name(buf)
print("Name: " .. name)
-- Get buffer lines
local lines = vim.api.nvim_buf_get_lines(buf, 0, 10, false)
for i, line in ipairs(lines) do
print(i .. ": " .. line)
end
Exercise 3.2: Window operations
-- Get current window
local win = vim.api.nvim_get_current_win()
-- Get window dimensions
local width = vim.api.nvim_win_get_width(win)
local height = vim.api.nvim_win_get_height(win)
print(string.format("Window: %dx%d", width, height))
-- Get cursor position
local cursor = vim.api.nvim_win_get_cursor(win)
print(string.format("Cursor: line %d, col %d", cursor[1], cursor[2]))
Exercise 3.3: User commands
-- Create command
vim.api.nvim_create_user_command('Hello', function(opts)
print("Hello, " .. (opts.args ~= "" and opts.args or "World"))
end, {
nargs = '?', -- Optional argument
desc = 'Say hello'
})
-- Usage: :Hello
-- Usage: :Hello Evan
Lesson 4: Autocommands
Concept: vim.api.nvim_create_autocmd for event-driven code.
Exercise 4.1: Basic autocmd
-- Run on file save
vim.api.nvim_create_autocmd('BufWritePre', {
pattern = '*.lua',
callback = function()
print("Saving Lua file...")
end,
})
Exercise 4.2: Autocmd group
-- Group prevents duplicate autocmds on reload
local group = vim.api.nvim_create_augroup('MyGroup', { clear = true })
vim.api.nvim_create_autocmd('FileType', {
group = group,
pattern = 'python',
callback = function()
vim.opt_local.tabstop = 4
vim.opt_local.shiftwidth = 4
end,
})
vim.api.nvim_create_autocmd('FileType', {
group = group,
pattern = 'lua',
callback = function()
vim.opt_local.tabstop = 2
vim.opt_local.shiftwidth = 2
end,
})
Exercise 4.3: Common autocmd patterns
local group = vim.api.nvim_create_augroup('UserConfig', { clear = true })
-- Highlight on yank
vim.api.nvim_create_autocmd('TextYankPost', {
group = group,
callback = function()
vim.highlight.on_yank({ higroup = 'IncSearch', timeout = 200 })
end,
})
-- Remove trailing whitespace
vim.api.nvim_create_autocmd('BufWritePre', {
group = group,
pattern = '*',
command = [[%s/\s\+$//e]],
})
Summary: What You Learned
| Concept | Syntax | Example |
|---|---|---|
Set option |
|
|
Append option |
|
|
Keymap |
|
|
Get buffer |
|
Returns buffer number |
Get lines |
|
0-indexed range |
User command |
|
|
Autocmd |
|
Run on events |
Augroup |
|
Group autocmds |
Exercises to Complete
-
[ ] Set your preferred tab/indent options
-
[ ] Create a keymap to toggle line numbers
-
[ ] Create a command that prints buffer info
-
[ ] Add autocmd to set Python-specific options
Next Session
Session 04: Plugins - lazy.nvim specs, module structure.
Session Log
| Timestamp | Notes |
|---|---|
Start |
<Record when you started> |
End |
<Record when you finished> |