# 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: ```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: ```lua -- 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: ```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: ```lua -- ~/.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`: ```lua require("my_plugin") ``` ## Autocmds (automatic commands) Run code on events (file open, save, etc.): ```lua vim.api.nvim_create_autocmd("FileType", { pattern = "python", callback = function(ev) vim.keymap.set('n', 't', ':!python %', { 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: ```lua -- 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: ```vim :lua print("hello") :lua vim.opt.number = true :luafile /path/to/script.lua ``` Useful for debugging. ## Example: custom grep command ```lua 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.