Neovim Lua API

vim.api — Core API

Buffer and window operations
-- Get/set current buffer content
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)  -- all lines
vim.api.nvim_buf_set_lines(0, 0, 0, false, { "-- header" })  -- prepend

-- Current buffer info
local bufnr = vim.api.nvim_get_current_buf()
local name = vim.api.nvim_buf_get_name(bufnr)
local ft = vim.bo[bufnr].filetype

-- Window operations
local winnr = vim.api.nvim_get_current_win()
local cursor = vim.api.nvim_win_get_cursor(winnr)  -- {row, col} (1-indexed row)
vim.api.nvim_win_set_cursor(winnr, { 10, 0 })      -- jump to line 10

-- Create commands
vim.api.nvim_create_user_command("Greet", function(opts)
  print("Hello, " .. opts.args)
end, { nargs = 1, desc = "Greet someone" })

Keymaps

vim.keymap.set
-- Basic keymap
vim.keymap.set("n", "<leader>w", ":w<CR>", { desc = "Save file" })

-- With callback
vim.keymap.set("n", "<leader>q", function()
  vim.cmd("confirm quit")
end, { desc = "Quit with confirmation" })

-- Multiple modes
vim.keymap.set({ "n", "v" }, "<leader>y", '"+y', { desc = "Yank to clipboard" })

-- Buffer-local
vim.keymap.set("n", "gd", vim.lsp.buf.definition, {
  buffer = bufnr,
  desc = "Go to definition",
})

-- Options
vim.keymap.set("n", "<leader>e", ":Explore<CR>", {
  silent = true,     -- no command echo
  noremap = true,    -- non-recursive (default in vim.keymap.set)
  desc = "File explorer",
})

Options

vim.opt and vim.o
-- vim.opt (handles lists, maps, sets properly)
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.shiftwidth = 2
vim.opt.tabstop = 2
vim.opt.expandtab = true
vim.opt.wrap = false

-- List-type options
vim.opt.wildignore:append({ "*.o", "*.pyc", "node_modules" })
vim.opt.path:prepend("**")

-- Window-local
vim.wo.signcolumn = "yes"

-- Buffer-local
vim.bo.filetype = "lua"

-- vim.g (global variables)
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
vim.g.loaded_netrw = 1                   -- disable netrw

Autocommands

vim.api.nvim_create_autocmd
-- Create augroup
local group = vim.api.nvim_create_augroup("MyGroup", { clear = true })

-- Autocommand
vim.api.nvim_create_autocmd("BufWritePre", {
  group = group,
  pattern = "*.lua",
  callback = function(args)
    -- trim trailing whitespace
    local lines = vim.api.nvim_buf_get_lines(args.buf, 0, -1, false)
    for i, line in ipairs(lines) do
      lines[i] = line:gsub("%s+$", "")
    end
    vim.api.nvim_buf_set_lines(args.buf, 0, -1, false, lines)
  end,
  desc = "Trim trailing whitespace in Lua files",
})

-- FileType-based config
vim.api.nvim_create_autocmd("FileType", {
  group = group,
  pattern = { "lua", "python" },
  callback = function()
    vim.bo.shiftwidth = 2
    vim.bo.tabstop = 2
  end,
})

-- Highlight on yank
vim.api.nvim_create_autocmd("TextYankPost", {
  group = group,
  callback = function()
    vim.highlight.on_yank({ timeout = 200 })
  end,
})

vim.fn and vim.cmd

Calling Vimscript from Lua
-- vim.fn -- call Vimscript functions
local home = vim.fn.expand("~")
local exists = vim.fn.filereadable("/etc/hosts")
local lines = vim.fn.systemlist("ls /tmp")

-- vim.cmd -- execute Ex commands
vim.cmd("colorscheme catppuccin-mocha")
vim.cmd.highlight("Normal guibg=NONE")
vim.cmd([[
  augroup legacy
    autocmd!
    autocmd BufRead *.md setlocal spell
  augroup END
]])

Notifications and UI

vim.notify and floating windows
-- Notifications
vim.notify("Build complete", vim.log.levels.INFO)
vim.notify("Error occurred", vim.log.levels.ERROR)

-- Schedule (defer to main loop)
vim.schedule(function()
  vim.notify("Deferred message")
end)

-- Floating window
local buf = vim.api.nvim_create_buf(false, true)  -- scratch buffer
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "Floating!", "Window" })
local win = vim.api.nvim_open_win(buf, true, {
  relative = "cursor",
  width = 30,
  height = 5,
  row = 1,
  col = 0,
  style = "minimal",
  border = "rounded",
})

vim.tbl — Table Utilities

Neovim table helpers
-- Deep merge (used everywhere in plugin configs)
local config = vim.tbl_deep_extend("force",
  { timeout = 30, ui = { border = "none" } },     -- defaults
  { ui = { border = "rounded" } }                  -- overrides
)
-- { timeout = 30, ui = { border = "rounded" } }

-- Other helpers
vim.tbl_contains({ "lua", "vim" }, "lua")          -- true
vim.tbl_keys({ a = 1, b = 2 })                    -- { "a", "b" }
vim.tbl_values({ a = 1, b = 2 })                  -- { 1, 2 }
vim.tbl_map(function(v) return v * 2 end, { 1, 2, 3 })  -- { 2, 4, 6 }
vim.tbl_filter(function(v) return v > 2 end, { 1, 2, 3, 4 })  -- { 3, 4 }
vim.tbl_isempty({})                                -- true
vim.tbl_count({ a = 1, b = 2 })                   -- 2

-- Deep comparison
vim.deep_equal({ a = { b = 1 } }, { a = { b = 1 } })  -- true