Table of Contents
Neovim Lua Scripting
Lua is Neovim's embedded scripting language. Instead of just configuration, you can write plugins and automate complex behavior in Lua. Neovim's API is accessible via the vim module.
The vim module
Access vim from Lua:
-- Options vim.opt.number = true vim.opt.shiftwidth = 4 -- Get option value local num = vim.opt.number:get() -- Commands vim.cmd("echo 'hello'") vim.cmd.vsplit("file.txt") -- fancy syntax -- Keybindings vim.keymap.set('n', 'gd', vim.lsp.buf.definition)
vim.api
Direct access to Neovim's internal API:
-- Create a command vim.api.nvim_create_user_command('JsonFormat', function() vim.cmd("%!jq .") end, {}) -- Create an autocmd vim.api.nvim_create_autocmd("BufWritePre", { callback = function() -- do something before save end, }) -- Get buffer content local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) -- Set buffer content vim.api.nvim_buf_set_lines(0, 0, -1, false, {"new", "lines"})
vim.fn
Call Vim functions from Lua:
-- File operations local file_exists = vim.fn.filereadable("path/to/file") == 1 -- String manipulation local lines = vim.fn.split("line1\nline2", "\n") -- System commands local output = vim.fn.system("ls -la")
Creating plugins
Plugins go in ~/.config/nvim/plugin/ and auto-load on startup:
-- ~/.config/nvim/plugin/my_plugin.lua local function my_function() print("Hello from plugin") end vim.api.nvim_create_user_command('MyCommand', my_function, {})
Or in ~/.config/nvim/lua/my_plugin/ with multiple files:
~/.config/nvim/lua/my_plugin/ ├── init.lua └── utils.lua
Then require in init.lua:
require("my_plugin")
Autocmds (automatic commands)
Run code on events (file open, save, etc.):
vim.api.nvim_create_autocmd("FileType", { pattern = "python", callback = function(ev) vim.keymap.set('n', '<leader>t', ':!python %<CR>', { buffer = true }) end, }) vim.api.nvim_create_autocmd("BufWritePost", { pattern = "*.py", callback = function() vim.cmd("!python -m py_compile %") end, })
pattern matches file type or name. callback is the Lua function.
Loops and tables
Lua syntax is straightforward:
-- Loop local files = {"a.txt", "b.txt", "c.txt"} for i, file in ipairs(files) do print(file) end -- Conditionals if vim.opt.number:get() then print("Numbers on") end -- Functions local function add(a, b) return a + b end local sum = add(2, 3) -- 5
Run Lua in command-line
Test Lua interactively:
:lua print("hello") :lua vim.opt.number = true :luafile /path/to/script.lua
Useful for debugging.
Example: custom grep command
vim.api.nvim_create_user_command('GrepTodo', function() vim.cmd("grep TODO .") vim.cmd("copen") -- open quickfix window end, {})
Then :GrepTodo searches project for TODO comments.
Performance
Lua runs in the main Neovim thread. Heavy computation blocks the editor. For intensive tasks, use external commands via vim.fn.system() or async jobs.
Lua is powerful for configuration and automation. Start with simple scripts (commands, keybindings), expand to full plugins as needed.
